[Discover] Enable expanded row view (#158623)

## Summary

Part of https://github.com/elastic/kibana/issues/154331

Enables the expanded row view for text based documents for both the
legacy and datagrid modes (the legacy was broken)

<img width="1899" alt="image"
src="edae78a9-6ef5-43db-ba3d-9019ecc72c57">


Note: I am hiding for now the single document view and surrounding
document view. I think that we should think about it more and if it
makes sense for ESQL. With ESQL if there is no @timestamp I see all my
data in the table. If I want to narrow the results I can use where and
limit. How should the surrounding documents work for a query with where
date field and with llimit? Does it make sense? Possibly not, because
with ESQL I can have the surrounding documents view in my main view bu
just changing the query. So I am hiding them for now, until we find a
good use case for that and decide how we want this to work.

### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [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

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Stratoula Kalafateli 2023-06-01 14:16:35 +03:00 committed by GitHub
parent d13f884ec3
commit 2bee02ffd0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 273 additions and 133 deletions

View file

@ -16,6 +16,7 @@ import { DocViewer } from '../../../services/doc_views/components/doc_viewer';
import { ElasticRequestState } from '../types';
import { useEsDocSearch } from '../../../hooks/use_es_doc_search';
import { useDiscoverServices } from '../../../hooks/use_discover_services';
import type { DataTableRecord } from '../../../types';
export interface DocProps {
/**
@ -38,6 +39,10 @@ export interface DocProps {
* Discover main view url
*/
referrer?: string;
/**
* Records fetched from text based query
*/
textBasedHits?: DataTableRecord[];
}
export function Doc(props: DocProps) {

View file

@ -208,6 +208,7 @@ function DiscoverDocumentsComponent({
isLoading={isDataLoading}
searchDescription={savedSearch.description}
sharedItemTitle={savedSearch.title}
isPlainRecord={isPlainRecord}
onAddColumn={onAddColumn}
onFilter={onAddFilter as DocViewFilterFn}
onMoveColumn={onMoveColumn}
@ -238,7 +239,7 @@ function DiscoverDocumentsComponent({
sampleSize={sampleSize}
searchDescription={savedSearch.description}
searchTitle={savedSearch.title}
setExpandedDoc={!isPlainRecord ? setExpandedDoc : undefined}
setExpandedDoc={setExpandedDoc}
showTimeCol={showTimeCol}
settings={grid}
onAddColumn={onAddColumn}
@ -252,6 +253,7 @@ function DiscoverDocumentsComponent({
onUpdateRowHeight={onUpdateRowHeight}
isSortEnabled={!isPlainRecord}
isPlainRecord={isPlainRecord}
query={query}
rowsPerPageState={rowsPerPage}
onUpdateRowsPerPage={onUpdateRowsPerPage}
onFieldEdited={onFieldEdited}

View file

@ -15,16 +15,12 @@
padding: 0;
}
.dscDiscoverGrid__textLanguageMode .euiDataGridRowCell.euiDataGridRowCell--firstColumn {
padding: $euiSizeXS;
}
.euiDataGridRowCell.euiDataGridRowCell--lastColumn {
border-right: none;
}
.dscDiscoverGrid__documentsMode .euiDataGridRowCell:first-of-type,
.dscDiscoverGrid__documentsMode .euiDataGrid--headerShade.euiDataGrid--bordersAll .euiDataGridHeaderCell:first-of-type {
.dscDiscoverGrid__table .euiDataGridRowCell:first-of-type,
.dscDiscoverGrid__table .euiDataGrid--headerShade.euiDataGrid--bordersAll .euiDataGridHeaderCell:first-of-type {
border-left: none;
border-right: none;
}

View file

@ -25,7 +25,7 @@ import {
} from '@elastic/eui';
import type { DataView } from '@kbn/data-views-plugin/public';
import type { SortOrder } from '@kbn/saved-search-plugin/public';
import { Filter } from '@kbn/es-query';
import type { AggregateQuery, Filter, Query } from '@kbn/es-query';
import { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import type { ToastsStart, IUiSettingsClient, HttpStart, CoreStart } from '@kbn/core/public';
import { DataViewFieldEditorStart } from '@kbn/data-view-field-editor-plugin/public';
@ -191,6 +191,10 @@ export interface DiscoverGridProps {
* Filters applied by saved search embeddable
*/
filters?: Filter[];
/**
* Query applied by KQL bar or text based editor
*/
query?: Query | AggregateQuery;
/**
* Saved search id used for links to single doc and surrounding docs in the flyout
*/
@ -224,6 +228,7 @@ export const DiscoverGrid = ({
expandedDoc,
onAddColumn,
filters,
query,
savedSearchId,
onFilter,
onRemoveColumn,
@ -596,11 +601,7 @@ export const DiscoverGrid = ({
data-title={searchTitle}
data-description={searchDescription}
data-document-number={displayedRows.length}
className={classnames(
className,
'dscDiscoverGrid__table',
isPlainRecord ? 'dscDiscoverGrid__textLanguageMode' : 'dscDiscoverGrid__documentsMode'
)}
className={classnames(className, 'dscDiscoverGrid__table')}
>
<EuiDataGridMemoized
aria-describedby={randomId}
@ -665,6 +666,7 @@ export const DiscoverGrid = ({
onAddColumn={onAddColumn}
onClose={() => setExpandedDoc(undefined)}
setExpandedDoc={setExpandedDoc}
query={query}
/>
)}
</span>

View file

@ -9,6 +9,7 @@
import React from 'react';
import { findTestSubject } from '@elastic/eui/lib/test';
import { mountWithIntl } from '@kbn/test-jest-helpers';
import type { Query, AggregateQuery } from '@kbn/es-query';
import { DiscoverGridFlyout, DiscoverGridFlyoutProps } from './discover_grid_flyout';
import { esHits } from '../../__mocks__/es_hits';
import { createFilterManagerMock } from '@kbn/data-plugin/public/query/filter_manager/filter_manager.mock';
@ -40,10 +41,12 @@ describe('Discover flyout', function () {
dataView,
hits,
hitIndex,
query,
}: {
dataView?: DataView;
hits?: DataTableRecord[];
hitIndex?: number;
query?: Query | AggregateQuery;
}) => {
const onClose = jest.fn();
const services = {
@ -71,6 +74,7 @@ describe('Discover flyout', function () {
hits:
hits ||
esHits.map((entry: EsHitRecord) => buildDataTableRecord(entry, dataView || dataViewMock)),
query,
onAddColumn: jest.fn(),
onClose,
onFilter: jest.fn(),
@ -192,4 +196,14 @@ describe('Discover flyout', function () {
findTestSubject(component, 'docTableDetailsFlyout').simulate('keydown', { key: 'ArrowRight' });
expect(props.setExpandedDoc).not.toHaveBeenCalled();
});
it('should not render single/surrounding views for text based', async () => {
const { component } = await mountComponent({
query: { sql: 'Select * from indexpattern' },
});
const singleDocumentView = findTestSubject(component, 'docTableRowAction');
expect(singleDocumentView.length).toBeFalsy();
const flyoutTitle = findTestSubject(component, 'docTableRowDetailsTitle');
expect(flyoutTitle.text()).toBe('Expanded row');
});
});

View file

@ -25,16 +25,18 @@ import {
EuiHideFor,
keys,
} from '@elastic/eui';
import { Filter } from '@kbn/es-query';
import type { Filter, Query, AggregateQuery } from '@kbn/es-query';
import { DocViewer } from '../../services/doc_views/components/doc_viewer/doc_viewer';
import { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
import { useNavigationProps } from '../../hooks/use_navigation_props';
import { useDiscoverServices } from '../../hooks/use_discover_services';
import { isTextBasedQuery } from '../../application/main/utils/is_text_based_query';
import type { DataTableRecord } from '../../types';
export interface DiscoverGridFlyoutProps {
savedSearchId?: string;
filters?: Filter[];
query?: Query | AggregateQuery;
columns: string[];
hit: DataTableRecord;
hits?: DataTableRecord[];
@ -61,6 +63,7 @@ export function DiscoverGridFlyout({
columns,
savedSearchId,
filters,
query,
onFilter,
onClose,
onRemoveColumn,
@ -68,6 +71,7 @@ export function DiscoverGridFlyout({
setExpandedDoc,
}: DiscoverGridFlyoutProps) {
const services = useDiscoverServices();
const isPlainRecord = isTextBasedQuery(query);
// Get actual hit with updated highlighted searches
const actualHit = useMemo(() => hits?.find(({ id }) => id === hit?.id) || hit, [hit, hits]);
const pageCount = useMemo<number>(() => (hits ? hits.length : 0), [hits]);
@ -120,80 +124,88 @@ export function DiscoverGridFlyout({
data-test-subj="docTableRowDetailsTitle"
>
<h2>
{i18n.translate('discover.grid.tableRow.detailHeading', {
defaultMessage: 'Expanded document',
})}
{isPlainRecord
? i18n.translate('discover.grid.tableRow.textBasedDetailHeading', {
defaultMessage: 'Expanded row',
})
: i18n.translate('discover.grid.tableRow.detailHeading', {
defaultMessage: 'Expanded document',
})}
</h2>
</EuiTitle>
<EuiSpacer size="s" />
<EuiFlexGroup responsive={false} gutterSize="s" alignItems="center">
<EuiHideFor sizes={['xs', 's', 'm']}>
<EuiFlexItem grow={false}>
<EuiText size="s">
<strong>
{i18n.translate('discover.grid.tableRow.viewText', {
defaultMessage: 'View:',
})}
</strong>
</EuiText>
</EuiFlexItem>
</EuiHideFor>
<EuiFlexItem grow={false}>
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
<EuiButtonEmpty
size="s"
iconSize="s"
iconType="document"
flush="left"
data-test-subj="docTableRowAction"
href={singleDocHref}
onClick={onOpenSingleDoc}
>
{i18n.translate('discover.grid.tableRow.viewSingleDocumentLinkTextSimple', {
defaultMessage: 'Single document',
})}
</EuiButtonEmpty>
</EuiFlexItem>
{dataView.isTimeBased() && dataView.id && (
<EuiFlexGroup alignItems="center" responsive={false} gutterSize="none">
{!isPlainRecord && (
<>
<EuiHideFor sizes={['xs', 's', 'm']}>
<EuiFlexItem grow={false}>
<EuiText size="s">
<strong>
{i18n.translate('discover.grid.tableRow.viewText', {
defaultMessage: 'View:',
})}
</strong>
</EuiText>
</EuiFlexItem>
</EuiHideFor>
<EuiFlexItem grow={false}>
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
<EuiButtonEmpty
size="s"
iconSize="s"
iconType="documents"
iconType="document"
flush="left"
onClick={onOpenContextView}
href={contextViewHref}
data-test-subj="docTableRowAction"
href={singleDocHref}
onClick={onOpenSingleDoc}
>
{i18n.translate(
'discover.grid.tableRow.viewSurroundingDocumentsLinkTextSimple',
{
defaultMessage: 'Surrounding documents',
}
)}
{i18n.translate('discover.grid.tableRow.viewSingleDocumentLinkTextSimple', {
defaultMessage: 'Single document',
})}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiIconTip
content={i18n.translate(
'discover.grid.tableRow.viewSurroundingDocumentsHover',
{
defaultMessage:
'Inspect documents that occurred before and after this document. Only pinned filters remain active in the Surrounding documents view.',
}
)}
type="questionInCircle"
color="subdued"
position="right"
iconProps={{
className: 'eui-alignTop',
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
{dataView.isTimeBased() && dataView.id && (
<EuiFlexGroup alignItems="center" responsive={false} gutterSize="none">
<EuiFlexItem grow={false}>
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
<EuiButtonEmpty
size="s"
iconSize="s"
iconType="documents"
flush="left"
onClick={onOpenContextView}
href={contextViewHref}
data-test-subj="docTableRowAction"
>
{i18n.translate(
'discover.grid.tableRow.viewSurroundingDocumentsLinkTextSimple',
{
defaultMessage: 'Surrounding documents',
}
)}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiIconTip
content={i18n.translate(
'discover.grid.tableRow.viewSurroundingDocumentsHover',
{
defaultMessage:
'Inspect documents that occurred before and after this document. Only pinned filters remain active in the Surrounding documents view.',
}
)}
type="questionInCircle"
color="subdued"
position="right"
iconProps={{
className: 'eui-alignTop',
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
)}
</>
)}
{activePage !== -1 && (
<EuiFlexItem data-test-subj={`dscDocNavigationPage-${activePage}`}>
@ -236,6 +248,7 @@ export function DiscoverGridFlyout({
})
);
}}
textBasedHits={isPlainRecord ? hits : undefined}
/>
</EuiFlyoutBody>
</EuiFlyout>

View file

@ -132,5 +132,17 @@ describe('Doc table row component', () => {
toggleButton.simulate('click');
expect(findTestSubject(component, 'docTableRowDetailsTitle').exists()).toBeTruthy();
});
it('should hide the single/surrounding views for text based languages', () => {
const props = {
...defaultProps,
isPlainRecord: true,
};
const component = mountComponent(props);
const toggleButton = findTestSubject(component, 'docTableExpandToggleColumn');
toggleButton.simulate('click');
expect(findTestSubject(component, 'docTableRowDetailsTitle').text()).toBe('Expanded row');
expect(findTestSubject(component, 'docTableRowAction').length).toBeFalsy();
});
});
});

View file

@ -31,8 +31,10 @@ export interface TableRowProps {
columns: string[];
filter: DocViewFilterFn;
filters?: Filter[];
isPlainRecord?: boolean;
savedSearchId?: string;
row: DataTableRecord;
rows: DataTableRecord[];
dataView: DataView;
useNewFieldsApi: boolean;
shouldShowFieldHandler: ShouldShowFieldInTableHandler;
@ -43,10 +45,12 @@ export interface TableRowProps {
export const TableRow = ({
filters,
isPlainRecord,
columns,
filter,
savedSearchId,
row,
rows,
dataView,
useNewFieldsApi,
shouldShowFieldHandler,
@ -212,6 +216,7 @@ export const TableRow = ({
columns={columns}
filters={filters}
savedSearchId={savedSearchId}
isPlainRecord={isPlainRecord}
>
<DocViewer
columns={columns}
@ -220,6 +225,7 @@ export const TableRow = ({
dataView={dataView}
onAddColumn={onAddColumn}
onRemoveColumn={onRemoveColumn}
textBasedHits={isPlainRecord ? rows : undefined}
/>
</TableRowDetails>
)}

View file

@ -23,6 +23,7 @@ interface TableRowDetailsProps {
dataView: DataView;
filters?: Filter[];
savedSearchId?: string;
isPlainRecord?: boolean;
}
export const TableRowDetails = ({
@ -35,6 +36,7 @@ export const TableRowDetails = ({
columns,
filters,
savedSearchId,
isPlainRecord,
}: TableRowDetailsProps) => {
const { singleDocHref, contextViewHref, onOpenSingleDoc, onOpenContextView } = useNavigationProps(
{
@ -58,55 +60,65 @@ export const TableRowDetails = ({
<EuiFlexItem grow={false}>
<EuiTitle size="xxs" data-test-subj="docTableRowDetailsTitle">
<h4>
<FormattedMessage
id="discover.docTable.tableRow.detailHeading"
defaultMessage="Expanded document"
/>
{isPlainRecord && (
<FormattedMessage
id="discover.grid.tableRow.textBasedDetailHeading"
defaultMessage="Expanded row"
/>
)}
{!isPlainRecord && (
<FormattedMessage
id="discover.docTable.tableRow.detailHeading"
defaultMessage="Expanded document"
/>
)}
</h4>
</EuiTitle>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="l" alignItems="center" responsive={false}>
<EuiFlexItem grow={false}>
{isTimeBased && (
/* eslint-disable-next-line @elastic/eui/href-or-on-click */
{!isPlainRecord && (
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="l" alignItems="center" responsive={false}>
<EuiFlexItem grow={false}>
{isTimeBased && (
/* eslint-disable-next-line @elastic/eui/href-or-on-click */
<EuiButtonEmpty
size="s"
iconSize="s"
iconType="document"
flush="left"
data-test-subj="docTableRowAction"
href={contextViewHref}
onClick={onOpenContextView}
>
<FormattedMessage
id="discover.docTable.tableRow.viewSurroundingDocumentsLinkText"
defaultMessage="View surrounding documents"
/>
</EuiButtonEmpty>
)}
</EuiFlexItem>
<EuiFlexItem grow={false}>
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
<EuiButtonEmpty
size="s"
iconSize="s"
iconType="document"
flush="left"
data-test-subj="docTableRowAction"
href={contextViewHref}
onClick={onOpenContextView}
href={singleDocHref}
onClick={onOpenSingleDoc}
>
<FormattedMessage
id="discover.docTable.tableRow.viewSurroundingDocumentsLinkText"
defaultMessage="View surrounding documents"
id="discover.docTable.tableRow.viewSingleDocumentLinkText"
defaultMessage="View single document"
/>
</EuiButtonEmpty>
)}
</EuiFlexItem>
<EuiFlexItem grow={false}>
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
<EuiButtonEmpty
size="s"
iconSize="s"
iconType="document"
flush="left"
data-test-subj="docTableRowAction"
href={singleDocHref}
onClick={onOpenSingleDoc}
>
<FormattedMessage
id="discover.docTable.tableRow.viewSingleDocumentLinkText"
defaultMessage="View single document"
/>
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
)}
</EuiFlexGroup>
<div data-test-subj="docViewer">{children}</div>
</td>

View file

@ -32,6 +32,7 @@ export function DiscoverDocTableEmbeddable(renderProps: DocTableEmbeddableProps)
searchDescription={renderProps.searchDescription}
sharedItemTitle={renderProps.sharedItemTitle}
isLoading={renderProps.isLoading}
isPlainRecord={renderProps.isPlainRecord}
dataTestSubj="embeddedSavedSearchDocTable"
DocViewer={DocViewer}
/>

View file

@ -61,6 +61,11 @@ export interface DocTableProps {
* Filters applied by embeddalbe
*/
filters?: Filter[];
/**
* Flag which identifies if Discover operates
* in text based mode (ESQL)
*/
isPlainRecord?: boolean;
/**
* Saved search id
*/
@ -114,6 +119,7 @@ export const DocTableWrapper = forwardRef(
render,
columns,
filters,
isPlainRecord,
savedSearchId,
rows,
dataView,
@ -187,6 +193,8 @@ export const DocTableWrapper = forwardRef(
onAddColumn={onAddColumn}
onRemoveColumn={onRemoveColumn}
DocViewer={DocViewer}
isPlainRecord={isPlainRecord}
rows={rows}
/>
));
},
@ -201,6 +209,8 @@ export const DocTableWrapper = forwardRef(
onAddColumn,
onRemoveColumn,
DocViewer,
isPlainRecord,
rows,
]
);

View file

@ -556,10 +556,13 @@ export class SavedSearchEmbeddable
return;
}
const useLegacyTable = this.services.uiSettings.get(DOC_TABLE_LEGACY);
const query = this.savedSearch.searchSource.getField('query');
const props = {
savedSearch: this.savedSearch,
searchProps,
useLegacyTable,
query,
};
if (searchProps.services) {
ReactDOM.render(

View file

@ -7,15 +7,17 @@
*/
import React from 'react';
import { AggregateQuery, Query } from '@kbn/es-query';
import { DiscoverGridEmbeddable, DiscoverGridEmbeddableProps } from './saved_search_grid';
import { DiscoverDocTableEmbeddable } from '../components/doc_table/create_doc_table_embeddable';
import { DocTableEmbeddableProps } from '../components/doc_table/doc_table_embeddable';
import { isTextBasedQuery } from '../application/main/utils/is_text_based_query';
import { SearchProps } from './saved_search_embeddable';
interface SavedSearchEmbeddableComponentProps {
searchProps: SearchProps;
useLegacyTable: boolean;
query?: AggregateQuery | Query;
}
const DiscoverDocTableEmbeddableMemoized = React.memo(DiscoverDocTableEmbeddable);
@ -24,14 +26,22 @@ const DiscoverGridEmbeddableMemoized = React.memo(DiscoverGridEmbeddable);
export function SavedSearchEmbeddableComponent({
searchProps,
useLegacyTable,
query,
}: SavedSearchEmbeddableComponentProps) {
if (useLegacyTable) {
return <DiscoverDocTableEmbeddableMemoized {...(searchProps as DocTableEmbeddableProps)} />;
const isPlainRecord = isTextBasedQuery(query);
return (
<DiscoverDocTableEmbeddableMemoized
{...(searchProps as DocTableEmbeddableProps)}
isPlainRecord={isPlainRecord}
/>
);
}
return (
<DiscoverGridEmbeddableMemoized
{...(searchProps as DiscoverGridEmbeddableProps)}
showFullScreenButton={false}
query={query}
className="dscDiscoverGrid"
/>
);

View file

@ -29,7 +29,7 @@ export function DiscoverGridEmbeddable(props: DiscoverGridEmbeddableProps) {
>
<DataGridMemoized
{...props}
setExpandedDoc={!props.isPlainRecord ? setExpandedDoc : undefined}
setExpandedDoc={setExpandedDoc}
expandedDoc={expandedDoc}
DocumentView={DiscoverGridFlyout}
/>

View file

@ -286,4 +286,39 @@ describe('Test of <Doc /> helper / hook', () => {
buildDataTableRecord(record),
]);
});
test('useEsDocSearch for text based languages', async () => {
const dataView = {
getComputedFields: () => [],
getIndexPattern: () => index,
};
const props = {
id: '1',
index: 'index1',
dataView,
textBasedHits: [
{
id: '1',
raw: { field1: 1, field2: 2 },
flattened: { field1: 1, field2: 2 },
},
],
} as unknown as DocProps;
const hook = renderHook((p: DocProps) => useEsDocSearch(p), {
initialProps: props,
wrapper: ({ children }) => (
<KibanaContextProvider services={services}>{children}</KibanaContextProvider>
),
});
expect(hook.result.current.slice(0, 2)).toEqual([
ElasticRequestState.Found,
{
id: '1',
raw: { field1: 1, field2: 2 },
flattened: { field1: 1, field2: 2 },
},
]);
});
});

View file

@ -27,6 +27,7 @@ export function useEsDocSearch({
index,
dataView,
requestSource,
textBasedHits,
}: DocProps): [ElasticRequestState, DataTableRecord | null, () => void] {
const [status, setStatus] = useState(ElasticRequestState.Loading);
const [hit, setHit] = useState<DataTableRecord | null>(null);
@ -65,8 +66,16 @@ export function useEsDocSearch({
}, [id, index, dataView, data.search, useNewFieldsApi, requestSource]);
useEffect(() => {
requestData();
}, [requestData]);
if (textBasedHits) {
const selectedHit = textBasedHits?.find((r) => r.id === id);
if (selectedHit) {
setStatus(ElasticRequestState.Found);
setHit(selectedHit);
}
} else {
requestData();
}
}, [id, requestData, textBasedHits]);
return [status, hit, requestData];
}

View file

@ -262,22 +262,25 @@ export class DiscoverPlugin
defaultMessage: 'JSON',
}),
order: 20,
component: ({ hit, dataView }) => (
<React.Suspense
fallback={
<DeferredSpinner>
<EuiSkeletonText />
</DeferredSpinner>
}
>
<SourceViewer
index={hit.raw._index}
id={hit.raw._id}
dataView={dataView}
hasLineNumbers
/>
</React.Suspense>
),
component: ({ hit, dataView, query, textBasedHits }) => {
return (
<React.Suspense
fallback={
<DeferredSpinner>
<EuiSkeletonText />
</DeferredSpinner>
}
>
<SourceViewer
index={hit.raw._index}
id={hit.raw._id ?? hit.id}
dataView={dataView}
textBasedHits={textBasedHits}
hasLineNumbers
/>
</React.Suspense>
);
},
});
const {

View file

@ -16,6 +16,7 @@ import { DataView } from '@kbn/data-views-plugin/public';
import { useDiscoverServices } from '../../../../hooks/use_discover_services';
import { JSONCodeEditorCommonMemoized } from '../../../../components/json_code_editor/json_code_editor_common';
import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '../../../../../common';
import type { DataTableRecord } from '../../../../types';
import { useEsDocSearch } from '../../../../hooks/use_es_doc_search';
import { ElasticRequestState } from '../../../../application/doc/types';
import { getHeight } from './get_height';
@ -24,6 +25,7 @@ interface SourceViewerProps {
id: string;
index: string;
dataView: DataView;
textBasedHits?: DataTableRecord[];
hasLineNumbers: boolean;
width?: number;
}
@ -40,6 +42,7 @@ export const DocViewerSource = ({
dataView,
width,
hasLineNumbers,
textBasedHits,
}: SourceViewerProps) => {
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor>();
const [editorHeight, setEditorHeight] = useState<number>();
@ -52,6 +55,7 @@ export const DocViewerSource = ({
index,
dataView,
requestSource: useNewFieldsApi,
textBasedHits,
});
useEffect(() => {

View file

@ -7,6 +7,7 @@
*/
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
import type { AggregateQuery, Query } from '@kbn/es-query';
import { DataTableRecord } from '../../types';
import { IgnoredReason } from '../../utils/get_ignored_reason';
@ -29,6 +30,8 @@ export interface DocViewRenderProps {
hit: DataTableRecord;
dataView: DataView;
columns?: string[];
query?: Query | AggregateQuery;
textBasedHits?: DataTableRecord[];
filter?: DocViewFilterFn;
onAddColumn?: (columnName: string) => void;
onRemoveColumn?: (columnName: string) => void;

View file

@ -77,7 +77,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(await testSubjects.exists('unifiedHistogramQueryHits')).to.be(true);
expect(await testSubjects.exists('discoverAlertsButton')).to.be(false);
expect(await testSubjects.exists('shareTopNavButton')).to.be(true);
expect(await testSubjects.exists('docTableExpandToggleColumn')).to.be(false);
expect(await testSubjects.exists('docTableExpandToggleColumn')).to.be(true);
expect(await testSubjects.exists('dataGridColumnSortingButton')).to.be(false);
expect(await testSubjects.exists('fieldListFiltersFieldTypeFilterToggle')).to.be(true);
await testSubjects.click('field-@message-showDetails');
@ -97,7 +97,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// here Lens suggests a heatmap so it is rendered
expect(await testSubjects.exists('unifiedHistogramChart')).to.be(true);
expect(await testSubjects.exists('heatmapChart')).to.be(true);
const cell = await dataGrid.getCellElement(0, 3);
const cell = await dataGrid.getCellElement(0, 4);
expect(await cell.getVisibleText()).to.be('2269');
});
@ -110,7 +110,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await monacoEditor.setCodeEditorValue(testQuery);
await testSubjects.click('querySubmitButton');
await PageObjects.header.waitUntilLoadingHasFinished();
let cell = await dataGrid.getCellElement(0, 3);
let cell = await dataGrid.getCellElement(0, 4);
expect(await cell.getVisibleText()).to.be('2269');
await PageObjects.timePicker.setAbsoluteRange(
'Sep 19, 2015 @ 06:31:44.000',
@ -120,7 +120,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(await testSubjects.exists('discoverNoResults')).to.be(true);
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.header.waitUntilLoadingHasFinished();
cell = await dataGrid.getCellElement(0, 3);
cell = await dataGrid.getCellElement(0, 4);
expect(await cell.getVisibleText()).to.be('2269');
});
@ -135,7 +135,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await testSubjects.click('querySubmitButton');
await PageObjects.header.waitUntilLoadingHasFinished();
const cell = await dataGrid.getCellElement(0, 3);
const cell = await dataGrid.getCellElement(0, 4);
expect(await cell.getVisibleText()).to.be('2269');
});
});