From 0e420138eb04b50454d08f8aced22bae12e89963 Mon Sep 17 00:00:00 2001 From: Dmitry Tomashevich <39378793+Dmitriynj@users.noreply.github.com> Date: Thu, 1 Jul 2021 12:59:36 +0300 Subject: [PATCH] [Discover] Replace doc viewer table with EuiInMemoryTable (#102149) (#103678) * [Discover] replace legacy table with euiInMemoryTable * [Discover] update styles, add badge * fix font in badge and adjust line height * add tooltip * [Discover] update unit tests, return actions column to left side * [Discover] update field name test snapshot * [Discover] update wording * [Discover] handle pagination, return formatting value styles * [Discover] fix failing stylelint error * [Discover] return responsive prop, update classes * [Discover] update test and meet formatting rules * improve table view on medium * remove extra file * [Discover] fix unit test * [Discover] align top vertically field name and action cells, disable table responsive design * [Discover] adjust styles for cross browser compatibility * [Discover] remove pagination optimize styles, update test * [Discover] fix eslint * [Discover] clean up styles * [Discover] fix single doc view * [Discover] add check lack of multifieldBadge Co-authored-by: Andrea Del Rio Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Andrea Del Rio Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/doc_viewer/doc_viewer.scss | 89 +++---- .../__snapshots__/field_name.test.tsx.snap | 84 ++++--- .../components/field_name/field_name.scss | 12 + .../components/field_name/field_name.tsx | 68 ++++-- .../components/table/table.test.tsx | 75 ++++-- .../application/components/table/table.tsx | 230 ++++++++---------- .../components/table/table_cell_actions.tsx | 60 +++++ .../components/table/table_cell_value.tsx | 66 +++++ .../components/table/table_columns.tsx | 92 +++++++ .../components/table/table_row.tsx | 112 --------- src/plugins/discover/public/plugin.tsx | 5 +- 11 files changed, 508 insertions(+), 385 deletions(-) create mode 100644 src/plugins/discover/public/application/components/field_name/field_name.scss create mode 100644 src/plugins/discover/public/application/components/table/table_cell_actions.tsx create mode 100644 src/plugins/discover/public/application/components/table/table_cell_value.tsx create mode 100644 src/plugins/discover/public/application/components/table/table_columns.tsx delete mode 100644 src/plugins/discover/public/application/components/table/table_row.tsx diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss b/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss index f5a4180207c331..12d56d564b8559 100644 --- a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss +++ b/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss @@ -1,82 +1,57 @@ -.kbnDocViewerTable { - @include euiBreakpoint('xs', 's','m') { - table-layout: fixed; - } -} - .kbnDocViewer { - pre, - .kbnDocViewer__value { - display: inline-block; - word-break: break-all; - word-wrap: break-word; - white-space: pre-wrap; - color: $euiColorFullShade; + .euiTableRowCell { vertical-align: top; - padding-top: $euiSizeXS * .5; - } - .kbnDocViewer__field { - padding-top: $euiSizeS; - } - - .kbnDocViewer__multifield_row:hover td { - background-color: transparent; - } - - .kbnDocViewer__multifield_title { - font-family: $euiFontFamily; } - .dscFieldName { - color: $euiColorDarkShade; + tr:first-child th { + border-bottom-color: transparent; } +} - td, - pre { - font-family: $euiCodeFontFamily; - } +.kbnDocViewer__tableRow { + font-size: $euiFontSizeXS; + font-family: $euiCodeFontFamily; - tr:first-child td { - border-top-color: transparent; + .kbnDocViewer__buttons { + // Show all icons if one is focused, + &:focus-within { + .kbnDocViewer__actionButton { + opacity: 1; + } + } } - tr:hover { + &:hover { .kbnDocViewer__actionButton { opacity: 1; } } -} -.kbnDocViewer__buttons, -.kbnDocViewer__field { - white-space: nowrap; -} -.kbnDocViewer__buttons { - width: 108px; + .kbnDocViewer__actionButton { + @include euiBreakpoint('m', 'l', 'xl') { + opacity: 0; + } - // Show all icons if one is focused, - &:focus-within { - .kbnDocViewer__actionButton { + &:focus { opacity: 1; } } } -.kbnDocViewer__field { - width: $euiSize * 10; - @include euiBreakpoint('xs', 's', 'm') { - width: $euiSize * 6; - } +.kbnDocViewer__tableActionsCell, +.kbnDocViewer__tableFieldNameCell { + align-items: flex-start; + padding: $euiSizeXS; } -.kbnDocViewer__actionButton { - @include euiBreakpoint('m', 'l', 'xl') { - opacity: 0; - } - - &:focus { - opacity: 1; - } +.kbnDocViewer__value { + display: inline-block; + word-break: break-all; + word-wrap: break-word; + white-space: pre-wrap; + line-height: $euiLineHeight; + color: $euiColorFullShade; + vertical-align: top; } .kbnDocViewer__warning { diff --git a/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap b/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap index 6b5e45f8a04488..284c77c96db786 100644 --- a/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap +++ b/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap @@ -1,11 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`FieldName renders a geo field 1`] = ` -
+Array [
-
+
,
- - - test.test.test + + + test.test.test + - -
- + + , +] `; exports[`FieldName renders a number field by providing a field record 1`] = ` -
+Array [
-
+
,
- - - test.test.test + + + test.test.test + - -
- + + , +] `; exports[`FieldName renders a string field by providing fieldType and fieldName 1`] = ` -
+Array [
-
+
,
- - - test + + + test + - -
- + + , +] `; diff --git a/src/plugins/discover/public/application/components/field_name/field_name.scss b/src/plugins/discover/public/application/components/field_name/field_name.scss new file mode 100644 index 00000000000000..edc4ea270d7554 --- /dev/null +++ b/src/plugins/discover/public/application/components/field_name/field_name.scss @@ -0,0 +1,12 @@ +.kbnDocViewer__fieldIcon { + padding-top: $euiSizeXS * 1.5; +} + +.kbnDocViewer__fieldName { + line-height: $euiLineHeight; + padding: $euiSizeXS; +} + +.kbnDocViewer__multiFieldBadge { + @include euiFont; +} diff --git a/src/plugins/discover/public/application/components/field_name/field_name.tsx b/src/plugins/discover/public/application/components/field_name/field_name.tsx index d89ce7eb051ee1..e8b6765b738a53 100644 --- a/src/plugins/discover/public/application/components/field_name/field_name.tsx +++ b/src/plugins/discover/public/application/components/field_name/field_name.tsx @@ -6,21 +6,23 @@ * Side Public License, v 1. */ -import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import React, { Fragment } from 'react'; +import './field_name.scss'; +import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; import { FieldIcon, FieldIconProps } from '../../../../../kibana_react/public'; import { getFieldTypeName } from './field_type_name'; -import { FieldMapping } from '../../doc_views/doc_views_types'; +import { IndexPatternField } from '../../../../../data/public'; // properties fieldType and fieldName are provided in kbn_doc_view // this should be changed when both components are deangularized interface Props { fieldName: string; fieldType: string; - fieldMapping?: FieldMapping; + fieldMapping?: IndexPatternField; fieldIconProps?: Omit; scripted?: boolean; - className?: string; } export function FieldName({ @@ -28,29 +30,57 @@ export function FieldName({ fieldMapping, fieldType, fieldIconProps, - className, scripted = false, }: Props) { const typeName = getFieldTypeName(fieldType); const displayName = fieldMapping && fieldMapping.displayName ? fieldMapping.displayName : fieldName; const tooltip = displayName !== fieldName ? `${fieldName} (${displayName})` : fieldName; + const isMultiField = !!fieldMapping?.spec?.subType?.multi; return ( - - + + - - - {displayName} - - - + + + + + {displayName} + + + + {isMultiField && ( + + + + + + )} + + ); } diff --git a/src/plugins/discover/public/application/components/table/table.test.tsx b/src/plugins/discover/public/application/components/table/table.test.tsx index bf27f1871cf24f..a38a9e41aa242f 100644 --- a/src/plugins/discover/public/application/components/table/table.test.tsx +++ b/src/plugins/discover/public/application/components/table/table.test.tsx @@ -9,7 +9,8 @@ import React from 'react'; import { mount } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; -import { DocViewTable } from './table'; +import { I18nProvider } from '@kbn/i18n/react'; +import { DocViewerTable, DocViewerTableProps } from './table'; import { indexPatterns, IndexPattern } from '../../../../../data/public'; import { ElasticSearchHit } from '../../doc_views/doc_views_types'; @@ -23,7 +24,7 @@ import { getServices } from '../../../kibana_services'; uiSettings: { get: (key: string) => { if (key === 'discover:showMultiFields') { - return false; + return true; } }, }, @@ -75,6 +76,14 @@ indexPattern.fields.getByName = (name: string) => { indexPattern.flattenHit = indexPatterns.flattenHitWrapper(indexPattern, indexPattern.metaFields); +const mountComponent = (props: DocViewerTableProps) => { + return mount( + + + + ); +}; + describe('DocViewTable at Discover', () => { // At Discover's main view, all buttons are rendered // check for existence of action buttons and warnings @@ -114,7 +123,7 @@ describe('DocViewTable at Discover', () => { onAddColumn: jest.fn(), onRemoveColumn: jest.fn(), }; - const component = mount(); + const component = mountComponent(props); [ { _property: '_index', @@ -210,7 +219,7 @@ describe('DocViewTable at Discover Context', () => { filter: jest.fn(), }; - const component = mount(); + const component = mountComponent(props); it(`renders no toggleColumnButton`, () => { const foundLength = findTestSubject(component, 'toggleColumnButtons').length; @@ -253,7 +262,7 @@ describe('DocViewTable at Discover Doc', () => { hit, indexPattern, }; - const component = mount(); + const component = mountComponent(props); const foundLength = findTestSubject(component, 'addInclusiveFilterButton').length; it(`renders no action buttons`, () => { @@ -381,20 +390,10 @@ describe('DocViewTable at Discover Doc with Fields API', () => { onAddColumn: jest.fn(), onRemoveColumn: jest.fn(), }; + it('renders multifield rows if showMultiFields flag is set', () => { - (getServices as jest.Mock).mockImplementationOnce(() => ({ - uiSettings: { - get: (key: string) => { - return key === 'discover:showMultiFields'; - }, - }, - })); - const component = mount(); - const categoryMultifieldRow = findTestSubject( - component, - 'tableDocViewRow-multifieldsTitle-category' - ); - expect(categoryMultifieldRow.length).toBe(1); + const component = mountComponent(props); + const categoryKeywordRow = findTestSubject(component, 'tableDocViewRow-category.keyword'); expect(categoryKeywordRow.length).toBe(1); @@ -404,23 +403,51 @@ describe('DocViewTable at Discover Doc with Fields API', () => { expect(findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname').length).toBe( 1 ); + + expect( + findTestSubject(component, 'tableDocViewRow-category.keyword-multifieldBadge').length + ).toBe(1); + + expect( + findTestSubject(component, 'tableDocViewRow-customer_first_name.keyword-multifieldBadge') + .length + ).toBe(1); + + expect( + findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname-multifieldBadge') + .length + ).toBe(1); }); it('does not render multifield rows if showMultiFields flag is not set', () => { - const component = mount(); - const categoryMultifieldRow = findTestSubject( - component, - 'tableDocViewRow-multifieldsTitle-category' - ); - expect(categoryMultifieldRow.length).toBe(0); + (getServices as jest.Mock).mockImplementationOnce(() => ({ + uiSettings: { + get: (key: string) => { + return key === 'discover:showMultiFields' && false; + }, + }, + })); + const component = mountComponent(props); + const categoryKeywordRow = findTestSubject(component, 'tableDocViewRow-category.keyword'); expect(categoryKeywordRow.length).toBe(0); expect(findTestSubject(component, 'tableDocViewRow-customer_first_name.keyword').length).toBe( 0 ); + expect(findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname').length).toBe( 0 ); + + expect( + findTestSubject(component, 'tableDocViewRow-customer_first_name.keyword-multifieldBadge') + .length + ).toBe(0); + + expect( + findTestSubject(component, 'tableDocViewRow-customer_first_name.nickname-multifieldBadge') + .length + ).toBe(0); }); }); diff --git a/src/plugins/discover/public/application/components/table/table.tsx b/src/plugins/discover/public/application/components/table/table.tsx index 4d24fe15519a17..065b146105a651 100644 --- a/src/plugins/discover/public/application/components/table/table.tsx +++ b/src/plugins/discover/public/application/components/table/table.tsx @@ -6,60 +6,67 @@ * Side Public License, v 1. */ -import React, { useState, useEffect, useCallback } from 'react'; -import { i18n } from '@kbn/i18n'; -import { DocViewTableRow } from './table_row'; -import { trimAngularSpan } from './table_helper'; -import { isNestedFieldParent } from '../../apps/main/utils/nested_fields'; -import { DocViewRenderProps } from '../../doc_views/doc_views_types'; -import { getServices } from '../../../kibana_services'; +import React, { useCallback, useMemo } from 'react'; +import { EuiInMemoryTable } from '@elastic/eui'; +import { IndexPattern, IndexPatternField } from '../../../../../data/public'; import { SHOW_MULTIFIELDS } from '../../../../common'; +import { getServices } from '../../../kibana_services'; +import { isNestedFieldParent } from '../../apps/main/utils/nested_fields'; +import { + DocViewFilterFn, + ElasticSearchHit, + DocViewRenderProps, +} from '../../doc_views/doc_views_types'; +import { ACTIONS_COLUMN, MAIN_COLUMNS } from './table_columns'; -const COLLAPSE_LINE_LENGTH = 350; +export interface DocViewerTableProps { + columns?: string[]; + filter?: DocViewFilterFn; + hit: ElasticSearchHit; + indexPattern?: IndexPattern; + onAddColumn?: (columnName: string) => void; + onRemoveColumn?: (columnName: string) => void; +} -export function DocViewTable({ +export interface FieldRecord { + action: { + isActive: boolean; + onFilter?: DocViewFilterFn; + onToggleColumn: (field: string) => void; + flattenedField: unknown; + }; + field: { + fieldName: string; + fieldType: string; + fieldMapping: IndexPatternField | undefined; + scripted: boolean; + }; + value: { + formattedField: unknown; + }; +} + +export const DocViewerTable = ({ + columns, hit, indexPattern, filter, - columns, onAddColumn, onRemoveColumn, -}: DocViewRenderProps) { - const [fieldRowOpen, setFieldRowOpen] = useState({} as Record); - const [multiFields, setMultiFields] = useState({} as Record); - const [fieldsWithParents, setFieldsWithParents] = useState([] as string[]); +}: DocViewRenderProps) => { const showMultiFields = getServices().uiSettings.get(SHOW_MULTIFIELDS); - useEffect(() => { - if (!indexPattern) { - return; - } - const mapping = indexPattern.fields.getByName; - const flattened = indexPattern.flattenHit(hit); - const map: Record = {}; - const arr: string[] = []; + const mapping = useCallback((name) => indexPattern?.fields.getByName(name), [ + indexPattern?.fields, + ]); - Object.keys(flattened).forEach((key) => { - const field = mapping(key); + const formattedHit = useMemo(() => indexPattern?.formatHit(hit, 'html'), [hit, indexPattern]); - if (field && field.spec?.subType?.multi?.parent) { - const parent = field.spec.subType.multi.parent; - if (!map[parent]) { - map[parent] = [] as string[]; - } - const value = map[parent]; - value.push(key); - map[parent] = value; - arr.push(key); - } - }); - if (showMultiFields) { - setMultiFields(map); - } - setFieldsWithParents(arr); - }, [indexPattern, hit, showMultiFields]); + const tableColumns = useMemo(() => { + return filter ? [ACTIONS_COLUMN, ...MAIN_COLUMNS] : MAIN_COLUMNS; + }, [filter]); - const toggleColumn = useCallback( + const onToggleColumn = useCallback( (field: string) => { if (!onRemoveColumn || !onAddColumn || !columns) { return; @@ -73,101 +80,62 @@ export function DocViewTable({ [onRemoveColumn, onAddColumn, columns] ); + const onSetRowProps = useCallback(({ field: { fieldName } }: FieldRecord) => { + return { + className: 'kbnDocViewer__tableRow', + 'data-test-subj': `tableDocViewRow-${fieldName}`, + }; + }, []); + if (!indexPattern) { return null; } - const mapping = indexPattern.fields.getByName; + const flattened = indexPattern.flattenHit(hit); - const formatted = indexPattern.formatHit(hit, 'html'); + const items: FieldRecord[] = Object.keys(flattened) + .filter((fieldName) => { + const fieldMapping = mapping(fieldName); + const isMultiField = !!fieldMapping?.spec?.subType?.multi; + return isMultiField ? showMultiFields : true; + }) + .sort((fieldA, fieldB) => { + const mappingA = mapping(fieldA); + const mappingB = mapping(fieldB); + const nameA = !mappingA || !mappingA.displayName ? fieldA : mappingA.displayName; + const nameB = !mappingB || !mappingB.displayName ? fieldB : mappingB.displayName; + return nameA.localeCompare(nameB); + }) + .map((fieldName) => { + const fieldMapping = mapping(fieldName); + const fieldType = isNestedFieldParent(fieldName, indexPattern) + ? 'nested' + : fieldMapping?.type; - function toggleValueCollapse(field: string) { - fieldRowOpen[field] = !fieldRowOpen[field]; - setFieldRowOpen({ ...fieldRowOpen }); - } + return { + action: { + onToggleColumn, + onFilter: filter, + isActive: !!columns?.includes(fieldName), + flattenedField: flattened[fieldName], + }, + field: { + fieldName, + fieldType: fieldType!, + scripted: Boolean(fieldMapping?.scripted), + fieldMapping, + }, + value: { formattedField: formattedHit[fieldName] }, + }; + }); return ( - - - {Object.keys(flattened) - .filter((field) => { - return !fieldsWithParents.includes(field); - }) - .sort((fieldA, fieldB) => { - const mappingA = mapping(fieldA); - const mappingB = mapping(fieldB); - const nameA = !mappingA || !mappingA.displayName ? fieldA : mappingA.displayName; - const nameB = !mappingB || !mappingB.displayName ? fieldB : mappingB.displayName; - return nameA.localeCompare(nameB); - }) - .map((field) => { - const valueRaw = flattened[field]; - const value = trimAngularSpan(String(formatted[field])); - - const isCollapsible = value.length > COLLAPSE_LINE_LENGTH; - const isCollapsed = isCollapsible && !fieldRowOpen[field]; - const displayUnderscoreWarning = !mapping(field) && field.indexOf('_') === 0; - - const fieldType = isNestedFieldParent(field, indexPattern) - ? 'nested' - : indexPattern.fields.getByName(field)?.type; - return ( - - toggleValueCollapse(field)} - onToggleColumn={() => toggleColumn(field)} - value={value} - valueRaw={valueRaw} - /> - {multiFields[field] ? ( - - - - - ) : null} - {multiFields[field] - ? multiFields[field].map((multiField) => { - return ( - { - toggleValueCollapse(multiField); - }} - onToggleColumn={() => toggleColumn(multiField)} - value={value} - valueRaw={valueRaw} - /> - ); - }) - : null} - - ); - })} - -
  - - {i18n.translate('discover.fieldChooser.discoverField.multiFields', { - defaultMessage: 'Multi fields', - })} - -
+ ); -} +}; diff --git a/src/plugins/discover/public/application/components/table/table_cell_actions.tsx b/src/plugins/discover/public/application/components/table/table_cell_actions.tsx new file mode 100644 index 00000000000000..3344797b4d32ad --- /dev/null +++ b/src/plugins/discover/public/application/components/table/table_cell_actions.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { DocViewTableRowBtnFilterRemove } from './table_row_btn_filter_remove'; +import { DocViewTableRowBtnFilterExists } from './table_row_btn_filter_exists'; +import { DocViewTableRowBtnToggleColumn } from './table_row_btn_toggle_column'; +import { DocViewTableRowBtnFilterAdd } from './table_row_btn_filter_add'; +import { IndexPatternField } from '../../../../../data/public'; +import { DocViewFilterFn } from '../../doc_views/doc_views_types'; + +interface TableActionsProps { + isActive: boolean; + fieldName: string; + flattenedField: unknown; + fieldMapping: IndexPatternField | undefined; + onFilter: DocViewFilterFn; + onToggleColumn: (field: string) => void; +} + +export const TableActions = ({ + isActive, + fieldName, + fieldMapping, + flattenedField, + onToggleColumn, + onFilter, +}: TableActionsProps) => { + const toggleColumn = () => { + onToggleColumn(fieldName); + }; + + return ( +
+ onFilter(fieldMapping, flattenedField, '+')} + /> + onFilter(fieldMapping, flattenedField, '-')} + /> + + onFilter('_exists_', fieldName, '+')} + scripted={fieldMapping && fieldMapping.scripted} + /> +
+ ); +}; diff --git a/src/plugins/discover/public/application/components/table/table_cell_value.tsx b/src/plugins/discover/public/application/components/table/table_cell_value.tsx new file mode 100644 index 00000000000000..de29068a827188 --- /dev/null +++ b/src/plugins/discover/public/application/components/table/table_cell_value.tsx @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import classNames from 'classnames'; +import React, { useCallback, useState } from 'react'; +import { IndexPatternField } from '../../../../../data/public'; +import { FieldRecord } from './table'; +import { trimAngularSpan } from './table_helper'; +import { DocViewTableRowBtnCollapse } from './table_row_btn_collapse'; +import { DocViewTableRowIconUnderscore } from './table_row_icon_underscore'; + +const COLLAPSE_LINE_LENGTH = 350; + +type TableFieldValueProps = FieldRecord['value'] & { + fieldName: string; + fieldMapping: IndexPatternField | undefined; +}; + +export const TableFieldValue = ({ + formattedField, + fieldName, + fieldMapping, +}: TableFieldValueProps) => { + const [fieldOpen, setFieldOpen] = useState(false); + + const value = trimAngularSpan(String(formattedField)); + const isCollapsible = value.length > COLLAPSE_LINE_LENGTH; + const isCollapsed = isCollapsible && !fieldOpen; + const displayUnderscoreWarning = !fieldMapping && fieldName.indexOf('_') === 0; + + const valueClassName = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention + kbnDocViewer__value: true, + 'truncate-by-height': isCollapsible && isCollapsed, + }); + + const onToggleCollapse = useCallback( + () => setFieldOpen((fieldOpenPrev: boolean) => !fieldOpenPrev), + [] + ); + + return ( +
+ {isCollapsible && ( + + )} + {displayUnderscoreWarning && } + {fieldName ? null :
{fieldName}: 
} +
+
+ ); +}; diff --git a/src/plugins/discover/public/application/components/table/table_columns.tsx b/src/plugins/discover/public/application/components/table/table_columns.tsx new file mode 100644 index 00000000000000..462362d543e7a2 --- /dev/null +++ b/src/plugins/discover/public/application/components/table/table_columns.tsx @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { EuiBasicTableColumn, EuiText } from '@elastic/eui'; +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { FieldName } from '../field_name/field_name'; +import { FieldRecord } from './table'; +import { TableActions } from './table_cell_actions'; +import { TableFieldValue } from './table_cell_value'; + +export const ACTIONS_COLUMN: EuiBasicTableColumn = { + field: 'action', + className: 'kbnDocViewer__tableActionsCell', + width: '108px', + name: ( + + + + + + ), + render: ( + { flattenedField, isActive, onFilter, onToggleColumn }: FieldRecord['action'], + { field: { fieldName, fieldMapping } }: FieldRecord + ) => { + return ( + + ); + }, +}; + +export const MAIN_COLUMNS: Array> = [ + { + field: 'field', + className: 'kbnDocViewer__tableFieldNameCell', + name: ( + + + + + + ), + render: ({ fieldName, fieldType, fieldMapping, scripted }: FieldRecord['field']) => { + return ( + + ); + }, + }, + { + field: 'value', + name: ( + + + + + + ), + render: ( + { formattedField }: FieldRecord['value'], + { field: { fieldName, fieldMapping } }: FieldRecord + ) => { + return ( + + ); + }, + }, +]; diff --git a/src/plugins/discover/public/application/components/table/table_row.tsx b/src/plugins/discover/public/application/components/table/table_row.tsx deleted file mode 100644 index e8977fda8576a8..00000000000000 --- a/src/plugins/discover/public/application/components/table/table_row.tsx +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import classNames from 'classnames'; -import React, { ReactNode } from 'react'; -import { FieldMapping, DocViewFilterFn } from '../../doc_views/doc_views_types'; -import { DocViewTableRowBtnFilterAdd } from './table_row_btn_filter_add'; -import { DocViewTableRowBtnFilterRemove } from './table_row_btn_filter_remove'; -import { DocViewTableRowBtnToggleColumn } from './table_row_btn_toggle_column'; -import { DocViewTableRowBtnCollapse } from './table_row_btn_collapse'; -import { DocViewTableRowBtnFilterExists } from './table_row_btn_filter_exists'; -import { DocViewTableRowIconUnderscore } from './table_row_icon_underscore'; -import { FieldName } from '../field_name/field_name'; - -export interface Props { - field?: string; - fieldMapping?: FieldMapping; - fieldType: string; - displayUnderscoreWarning: boolean; - isCollapsible: boolean; - isColumnActive: boolean; - isCollapsed: boolean; - onToggleCollapse: () => void; - onFilter?: DocViewFilterFn; - onToggleColumn?: () => void; - value: string | ReactNode; - valueRaw: unknown; -} - -export function DocViewTableRow({ - field, - fieldMapping, - fieldType, - displayUnderscoreWarning, - isCollapsible, - isCollapsed, - isColumnActive, - onFilter, - onToggleCollapse, - onToggleColumn, - value, - valueRaw, -}: Props) { - const valueClassName = classNames({ - // eslint-disable-next-line @typescript-eslint/naming-convention - kbnDocViewer__value: true, - 'truncate-by-height': isCollapsible && isCollapsed, - }); - const key = field ? field : fieldMapping?.displayName; - return ( - - {typeof onFilter === 'function' && ( - - onFilter(fieldMapping, valueRaw, '+')} - /> - onFilter(fieldMapping, valueRaw, '-')} - /> - {typeof onToggleColumn === 'function' && ( - - )} - onFilter('_exists_', field, '+')} - scripted={fieldMapping && fieldMapping.scripted} - /> - - )} - - {field ? ( - - ) : ( -   - )} - - - {isCollapsible && ( - - )} - {displayUnderscoreWarning && } - {field ? null :
{key}: 
} -
- - - ); -} diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index ec89f7516e92d1..3e31fe1d46d459 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -36,8 +36,7 @@ import { DEFAULT_APP_CATEGORIES } from '../../../core/public'; import { UrlGeneratorState } from '../../share/public'; import { DocViewInput, DocViewInputFn } from './application/doc_views/doc_views_types'; import { DocViewsRegistry } from './application/doc_views/doc_views_registry'; -import { DocViewTable } from './application/components/table/table'; - +import { DocViewerTable } from './application/components/table/table'; import { setDocViewsRegistry, setUrlTracker, @@ -252,7 +251,7 @@ export class DiscoverPlugin defaultMessage: 'Table', }), order: 10, - component: DocViewTable, + component: DocViewerTable, }); this.docViewsRegistry.addDocView({ title: i18n.translate('discover.docViews.json.jsonTitle', {