From 4a49e6175feeec958713bdc678698f35db67cc78 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 7 Oct 2021 19:29:40 +0300 Subject: [PATCH 01/24] [Discover] move source field formatter to discover --- .../doc_table/components/table_row.tsx | 28 ++++--- .../doc_table/doc_table_wrapper.tsx | 2 + .../doc_table/lib/formatters/mocks.ts | 42 +++++++++++ .../lib/{ => formatters}/row_formatter.scss | 0 .../{ => formatters}/row_formatter.test.ts | 38 +--------- .../lib/{ => formatters}/row_formatter.tsx | 4 +- .../lib/formatters/source_formatter.test.tsx | 40 ++++++++++ .../lib/formatters/source_formatter.tsx | 59 +++++++++++++++ .../common/constants/base_formatters.ts | 2 - .../field_formats/common/converters/index.ts | 1 - .../common/converters/source.test.ts | 49 ------------- .../common/converters/source.tsx | 73 ------------------- src/plugins/field_formats/common/index.ts | 5 +- 13 files changed, 168 insertions(+), 175 deletions(-) create mode 100644 src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/mocks.ts rename src/plugins/discover/public/application/apps/main/components/doc_table/lib/{ => formatters}/row_formatter.scss (100%) rename src/plugins/discover/public/application/apps/main/components/doc_table/lib/{ => formatters}/row_formatter.test.ts (85%) rename src/plugins/discover/public/application/apps/main/components/doc_table/lib/{ => formatters}/row_formatter.tsx (96%) create mode 100644 src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.test.tsx create mode 100644 src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx delete mode 100644 src/plugins/field_formats/common/converters/source.test.ts delete mode 100644 src/plugins/field_formats/common/converters/source.tsx diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx index 8d56f2adeaf65..2b96a1aa6f6b9 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx @@ -17,7 +17,8 @@ import { ElasticSearchHit, DocViewFilterFn } from '../../../../../doc_views/doc_ import { getContextUrl } from '../../../../../helpers/get_context_url'; import { getSingleDocUrl } from '../../../../../helpers/get_single_doc_url'; import { TableRowDetails } from './table_row_details'; -import { formatRow, formatTopLevelObject } from '../lib/row_formatter'; +import { formatRow, formatTopLevelObject } from '../lib/formatters/row_formatter'; +import { formatSource } from '../lib/formatters/source_formatter'; export type DocTableRow = ElasticSearchHit & { isAnchor?: boolean; @@ -32,6 +33,7 @@ export interface TableRowProps { onRemoveColumn?: (column: string) => void; useNewFieldsApi: boolean; hideTimeColumn: boolean; + isShortDots: boolean; filterManager: FilterManager; addBasePath: (path: string) => string; fieldsToShow: string[]; @@ -45,6 +47,7 @@ export const TableRow = ({ useNewFieldsApi, fieldsToShow, hideTimeColumn, + isShortDots, onAddColumn, onRemoveColumn, filterManager, @@ -63,18 +66,23 @@ export const TableRow = ({ // toggle display of the rows details, a full list of the fields from each row const toggleRow = () => setOpen((prevOpen) => !prevOpen); - /** - * Fill an element with the value of a field - */ - const displayField = (fieldName: string) => { + const formatField = (fieldName: string) => { + if (fieldName === '_source') { + return formatSource({ + hit: row, + indexPattern, + isShortDots, + }); + } + const formattedField = indexPattern.formatField(row, fieldName); // field formatters take care of escaping // eslint-disable-next-line react/no-danger - const fieldElement = ; - - return
{fieldElement}
; + const element = ; + return
{element}
; }; + const inlineFilter = useCallback( (column: string, type: '+' | '-') => { const field = indexPattern.fields.getByName(column); @@ -116,7 +124,7 @@ export const TableRow = ({ World', + also: 'with "quotes" or \'single quotes\'', + }, +} as DocTableRow; + +const createIndexPattern = () => { + const id = 'my-index'; + const { + type, + version, + attributes: { timeFieldName, fields, title }, + } = stubbedSavedObjectIndexPattern(id); + + return new IndexPattern({ + spec: { id, type, version, timeFieldName, fields: JSON.parse(fields), title }, + fieldFormats: fieldFormatsMock, + shortDotsEnable: false, + metaFields: [], + }); +}; + +export const indexPattern = createIndexPattern(); diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.scss b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.scss similarity index 100% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.scss rename to src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.scss diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.test.ts b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.test.ts similarity index 85% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.test.ts rename to src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.test.ts index 9cd2959f5d72a..c580dd9569243 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.test.ts +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.test.ts @@ -8,43 +8,11 @@ import ReactDOM from 'react-dom/server'; import { formatRow, formatTopLevelObject } from './row_formatter'; -import { IndexPattern } from '../../../../../../../../data/common'; -import { fieldFormatsMock } from '../../../../../../../../field_formats/common/mocks'; -import { setServices } from '../../../../../../kibana_services'; -import { DiscoverServices } from '../../../../../../build_services'; -import { stubbedSavedObjectIndexPattern } from '../../../../../../../../data/common/stubs'; +import { setServices } from '../../../../../../../kibana_services'; +import { DiscoverServices } from '../../../../../../../build_services'; +import { indexPattern, hit } from './mocks'; describe('Row formatter', () => { - const hit = { - _id: 'a', - _type: 'doc', - _score: 1, - _source: { - foo: 'bar', - number: 42, - hello: '

World

', - also: 'with "quotes" or \'single quotes\'', - }, - }; - - const createIndexPattern = () => { - const id = 'my-index'; - const { - type, - version, - attributes: { timeFieldName, fields, title }, - } = stubbedSavedObjectIndexPattern(id); - - return new IndexPattern({ - spec: { id, type, version, timeFieldName, fields: JSON.parse(fields), title }, - fieldFormats: fieldFormatsMock, - shortDotsEnable: false, - metaFields: [], - }); - }; - - const indexPattern = createIndexPattern(); - const fieldsToShow = indexPattern.fields.getAll().map((fld) => fld.name); // Realistic response with alphabetical insertion order diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx similarity index 96% rename from src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx rename to src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx index 14cf1839107e7..e3cc3f2e18c09 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx @@ -8,8 +8,8 @@ import React, { Fragment } from 'react'; import type { IndexPattern } from 'src/plugins/data/common'; -import { MAX_DOC_FIELDS_DISPLAYED } from '../../../../../../../common'; -import { getServices } from '../../../../../../kibana_services'; +import { MAX_DOC_FIELDS_DISPLAYED } from '../../../../../../../../common'; +import { getServices } from '../../../../../../../kibana_services'; import './row_formatter.scss'; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.test.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.test.tsx new file mode 100644 index 0000000000000..bb0ada208a3d2 --- /dev/null +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.test.tsx @@ -0,0 +1,40 @@ +/* + * 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 { formatSource } from './source_formatter'; +import { hit, indexPattern } from './mocks'; + +describe('_source formatter', () => { + it('should format properly', () => { + const element = formatSource({ hit, indexPattern, isShortDots: true }); + expect(element).toMatchInlineSnapshot(` + World", + ], + Array [ + "number", + 42, + ], + ] + } + /> + `); + }); +}); diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx new file mode 100644 index 0000000000000..31f95cafe631a --- /dev/null +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx @@ -0,0 +1,59 @@ +/* + * 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, { Fragment } from 'react'; +import { escape } from 'lodash'; +import { DocTableRow } from '../../components/table_row'; +import { shortenDottedString } from '../../../../../../../../../field_formats/common'; +import { IndexPattern } from '../../../../../../../../../data/public'; + +interface Props { + defPairs: Array<[string, string]>; +} + +const TemplateComponent = ({ defPairs }: Props) => { + return ( +
+ {defPairs.map((pair, idx) => ( + +
+
{' '} + + ))} +
+ ); +}; + +export const formatSource = ({ + hit, + indexPattern, + isShortDots, +}: { + hit: DocTableRow; + indexPattern: IndexPattern; + isShortDots: boolean; +}) => { + const highlights: Record = (hit && hit.highlight) || {}; + // TODO: remove index pattern dependency + const formatted = hit ? indexPattern.formatHit(hit) : {}; + const highlightPairs: Array<[string, string]> = []; + const sourcePairs: Array<[string, string]> = []; + + Object.keys(formatted).forEach((key) => { + const pairs = highlights[key] ? highlightPairs : sourcePairs; + const newField = isShortDots ? shortenDottedString(key) : key; + const val = formatted![key]; + pairs.push([newField as string, val]); + }, []); + + return ; +}; diff --git a/src/plugins/field_formats/common/constants/base_formatters.ts b/src/plugins/field_formats/common/constants/base_formatters.ts index 2fffc3b918482..90c78c34a82c6 100644 --- a/src/plugins/field_formats/common/constants/base_formatters.ts +++ b/src/plugins/field_formats/common/constants/base_formatters.ts @@ -17,7 +17,6 @@ import { NumberFormat, PercentFormat, RelativeDateFormat, - SourceFormat, StaticLookupFormat, StringFormat, TruncateFormat, @@ -34,7 +33,6 @@ export const baseFormatters: FieldFormatInstanceType[] = [ NumberFormat, PercentFormat, RelativeDateFormat, - SourceFormat, StaticLookupFormat, StringFormat, TruncateFormat, diff --git a/src/plugins/field_formats/common/converters/index.ts b/src/plugins/field_formats/common/converters/index.ts index 074ae7391659f..30d7c8128c822 100644 --- a/src/plugins/field_formats/common/converters/index.ts +++ b/src/plugins/field_formats/common/converters/index.ts @@ -14,7 +14,6 @@ export { IpFormat } from './ip'; export { NumberFormat } from './number'; export { PercentFormat } from './percent'; export { StringFormat } from './string'; -export { SourceFormat } from './source'; export { ColorFormat } from './color'; export { TruncateFormat } from './truncate'; export { BoolFormat } from './boolean'; diff --git a/src/plugins/field_formats/common/converters/source.test.ts b/src/plugins/field_formats/common/converters/source.test.ts deleted file mode 100644 index 298c93dac8c4e..0000000000000 --- a/src/plugins/field_formats/common/converters/source.test.ts +++ /dev/null @@ -1,49 +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 { SourceFormat } from './source'; -import { HtmlContextTypeConvert } from '../types'; -import { HTML_CONTEXT_TYPE } from '../content_types'; - -describe('Source Format', () => { - let convertHtml: Function; - - beforeEach(() => { - const source = new SourceFormat({}, jest.fn()); - - convertHtml = source.getConverterFor(HTML_CONTEXT_TYPE) as HtmlContextTypeConvert; - }); - - test('should use the text content type if a field is not passed', () => { - const hit = { - foo: 'bar', - number: 42, - hello: '

World

', - also: 'with "quotes" or \'single quotes\'', - }; - - expect(convertHtml(hit)).toBe( - '{"foo":"bar","number":42,"hello":"<h1>World</h1>","also":"with \\"quotes\\" or 'single quotes'"}' - ); - }); - - test('should render a description list if a field is passed', () => { - const hit = { - foo: 'bar', - number: 42, - hello: '

World

', - also: 'with "quotes" or \'single quotes\'', - }; - - expect( - convertHtml(hit, { field: 'field', indexPattern: { formatHit: (h: string) => h }, hit }) - ).toMatchInlineSnapshot( - `"
foo:
bar
number:
42
hello:

World

also:
with \\"quotes\\" or 'single quotes'
"` - ); - }); -}); diff --git a/src/plugins/field_formats/common/converters/source.tsx b/src/plugins/field_formats/common/converters/source.tsx deleted file mode 100644 index 1caffb5bfb9a8..0000000000000 --- a/src/plugins/field_formats/common/converters/source.tsx +++ /dev/null @@ -1,73 +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 { KBN_FIELD_TYPES } from '@kbn/field-types'; -import React, { Fragment } from 'react'; -import ReactDOM from 'react-dom/server'; -import { escape, keys } from 'lodash'; -import { shortenDottedString } from '../utils'; -import { FieldFormat } from '../field_format'; -import { TextContextTypeConvert, HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; -import { FORMATS_UI_SETTINGS } from '../constants/ui_settings'; - -interface Props { - defPairs: Array<[string, string]>; -} -const TemplateComponent = ({ defPairs }: Props) => { - return ( -
- {defPairs.map((pair, idx) => ( - -
-
{' '} - - ))} -
- ); -}; - -/** @public */ -export class SourceFormat extends FieldFormat { - static id = FIELD_FORMAT_IDS._SOURCE; - static title = '_source'; - static fieldType = KBN_FIELD_TYPES._SOURCE; - - textConvert: TextContextTypeConvert = (value: string) => JSON.stringify(value); - - htmlConvert: HtmlContextTypeConvert = (value: string, options = {}) => { - const { field, hit, indexPattern } = options; - - if (!field) { - const converter = this.getConverterFor('text') as Function; - - return escape(converter(value)); - } - - const highlights: Record = (hit && hit.highlight) || {}; - // TODO: remove index pattern dependency - const formatted = hit ? indexPattern!.formatHit(hit) : {}; - const highlightPairs: Array<[string, string]> = []; - const sourcePairs: Array<[string, string]> = []; - const isShortDots = this.getConfig!(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE); - - keys(formatted).forEach((key) => { - const pairs = highlights[key] ? highlightPairs : sourcePairs; - const newField = isShortDots ? shortenDottedString(key) : key; - const val = formatted![key]; - pairs.push([newField as string, val]); - }, []); - - return ReactDOM.renderToStaticMarkup( - - ); - }; -} diff --git a/src/plugins/field_formats/common/index.ts b/src/plugins/field_formats/common/index.ts index aeb5e0af220db..21ef940b132a5 100644 --- a/src/plugins/field_formats/common/index.ts +++ b/src/plugins/field_formats/common/index.ts @@ -24,15 +24,14 @@ export { NumberFormat, PercentFormat, RelativeDateFormat, - SourceFormat, - StaticLookupFormat, + StaticLookupF ormat, UrlFormat, StringFormat, TruncateFormat, HistogramFormat, } from './converters'; -export { getHighlightRequest } from './utils'; +export { getHighlightRequest, shortenDottedString } from './utils'; export { DEFAULT_CONVERTER_COLOR } from './constants/color_default'; export { FORMATS_UI_SETTINGS } from './constants/ui_settings'; From 7024757f80c7b287a351995cbb97e3beaaea1cd2 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 7 Oct 2021 19:51:50 +0300 Subject: [PATCH 02/24] [Discover] cleanup source field from field formatters --- api_docs/field_formats.json | 167 ---------------------- src/plugins/field_formats/common/index.ts | 2 +- 2 files changed, 1 insertion(+), 168 deletions(-) diff --git a/api_docs/field_formats.json b/api_docs/field_formats.json index 2cd5beb47d67e..fc5c2530801ad 100644 --- a/api_docs/field_formats.json +++ b/api_docs/field_formats.json @@ -3756,173 +3756,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat", - "type": "Class", - "tags": [], - "label": "SourceFormat", - "description": [], - "signature": [ - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.SourceFormat", - "text": "SourceFormat" - }, - " extends ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormat", - "text": "FieldFormat" - } - ], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat.id", - "type": "Enum", - "tags": [], - "label": "id", - "description": [], - "signature": [ - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FIELD_FORMAT_IDS", - "text": "FIELD_FORMAT_IDS" - } - ], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false - }, - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat.title", - "type": "string", - "tags": [], - "label": "title", - "description": [], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false - }, - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat.fieldType", - "type": "Enum", - "tags": [], - "label": "fieldType", - "description": [], - "signature": [ - { - "pluginId": "@kbn/field-types", - "scope": "server", - "docId": "kibKbnFieldTypesPluginApi", - "section": "def-server.KBN_FIELD_TYPES", - "text": "KBN_FIELD_TYPES" - } - ], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false - }, - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat.textConvert", - "type": "Function", - "tags": [], - "label": "textConvert", - "description": [], - "signature": [ - "(value: string) => string" - ], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat.textConvert.$1", - "type": "string", - "tags": [], - "label": "value", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat.htmlConvert", - "type": "Function", - "tags": [], - "label": "htmlConvert", - "description": [], - "signature": [ - "(value: string, options?: ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.HtmlContextTypeOptions", - "text": "HtmlContextTypeOptions" - }, - " | undefined) => string" - ], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false, - "children": [ - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat.htmlConvert.$1", - "type": "string", - "tags": [], - "label": "value", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "fieldFormats", - "id": "def-common.SourceFormat.htmlConvert.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.HtmlContextTypeOptions", - "text": "HtmlContextTypeOptions" - }, - " | undefined" - ], - "path": "src/plugins/field_formats/common/converters/source.tsx", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, { "parentPluginId": "fieldFormats", "id": "def-common.StaticLookupFormat", diff --git a/src/plugins/field_formats/common/index.ts b/src/plugins/field_formats/common/index.ts index 21ef940b132a5..0295dd266c2e1 100644 --- a/src/plugins/field_formats/common/index.ts +++ b/src/plugins/field_formats/common/index.ts @@ -24,7 +24,7 @@ export { NumberFormat, PercentFormat, RelativeDateFormat, - StaticLookupF ormat, + StaticLookupFormat, UrlFormat, StringFormat, TruncateFormat, From 66c0f9dd678181e5684ab4c341266554b1ac435d Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Fri, 8 Oct 2021 13:57:16 +0300 Subject: [PATCH 03/24] [Discover] return source field format --- api_docs/field_formats.json | 167 ++++++++++++++++++ .../common/constants/base_formatters.ts | 2 + .../field_formats/common/converters/index.ts | 1 + .../common/converters/source.test.ts | 49 +++++ .../common/converters/source.tsx | 75 ++++++++ 5 files changed, 294 insertions(+) create mode 100644 src/plugins/field_formats/common/converters/source.test.ts create mode 100644 src/plugins/field_formats/common/converters/source.tsx diff --git a/api_docs/field_formats.json b/api_docs/field_formats.json index fc5c2530801ad..2cd5beb47d67e 100644 --- a/api_docs/field_formats.json +++ b/api_docs/field_formats.json @@ -3756,6 +3756,173 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat", + "type": "Class", + "tags": [], + "label": "SourceFormat", + "description": [], + "signature": [ + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.SourceFormat", + "text": "SourceFormat" + }, + " extends ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormat", + "text": "FieldFormat" + } + ], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat.id", + "type": "Enum", + "tags": [], + "label": "id", + "description": [], + "signature": [ + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FIELD_FORMAT_IDS", + "text": "FIELD_FORMAT_IDS" + } + ], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false + }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false + }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat.fieldType", + "type": "Enum", + "tags": [], + "label": "fieldType", + "description": [], + "signature": [ + { + "pluginId": "@kbn/field-types", + "scope": "server", + "docId": "kibKbnFieldTypesPluginApi", + "section": "def-server.KBN_FIELD_TYPES", + "text": "KBN_FIELD_TYPES" + } + ], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false + }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat.textConvert", + "type": "Function", + "tags": [], + "label": "textConvert", + "description": [], + "signature": [ + "(value: string) => string" + ], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat.textConvert.$1", + "type": "string", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat.htmlConvert", + "type": "Function", + "tags": [], + "label": "htmlConvert", + "description": [], + "signature": [ + "(value: string, options?: ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.HtmlContextTypeOptions", + "text": "HtmlContextTypeOptions" + }, + " | undefined) => string" + ], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat.htmlConvert.$1", + "type": "string", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "fieldFormats", + "id": "def-common.SourceFormat.htmlConvert.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.HtmlContextTypeOptions", + "text": "HtmlContextTypeOptions" + }, + " | undefined" + ], + "path": "src/plugins/field_formats/common/converters/source.tsx", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fieldFormats", "id": "def-common.StaticLookupFormat", diff --git a/src/plugins/field_formats/common/constants/base_formatters.ts b/src/plugins/field_formats/common/constants/base_formatters.ts index 90c78c34a82c6..2fffc3b918482 100644 --- a/src/plugins/field_formats/common/constants/base_formatters.ts +++ b/src/plugins/field_formats/common/constants/base_formatters.ts @@ -17,6 +17,7 @@ import { NumberFormat, PercentFormat, RelativeDateFormat, + SourceFormat, StaticLookupFormat, StringFormat, TruncateFormat, @@ -33,6 +34,7 @@ export const baseFormatters: FieldFormatInstanceType[] = [ NumberFormat, PercentFormat, RelativeDateFormat, + SourceFormat, StaticLookupFormat, StringFormat, TruncateFormat, diff --git a/src/plugins/field_formats/common/converters/index.ts b/src/plugins/field_formats/common/converters/index.ts index 30d7c8128c822..074ae7391659f 100644 --- a/src/plugins/field_formats/common/converters/index.ts +++ b/src/plugins/field_formats/common/converters/index.ts @@ -14,6 +14,7 @@ export { IpFormat } from './ip'; export { NumberFormat } from './number'; export { PercentFormat } from './percent'; export { StringFormat } from './string'; +export { SourceFormat } from './source'; export { ColorFormat } from './color'; export { TruncateFormat } from './truncate'; export { BoolFormat } from './boolean'; diff --git a/src/plugins/field_formats/common/converters/source.test.ts b/src/plugins/field_formats/common/converters/source.test.ts new file mode 100644 index 0000000000000..298c93dac8c4e --- /dev/null +++ b/src/plugins/field_formats/common/converters/source.test.ts @@ -0,0 +1,49 @@ +/* + * 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 { SourceFormat } from './source'; +import { HtmlContextTypeConvert } from '../types'; +import { HTML_CONTEXT_TYPE } from '../content_types'; + +describe('Source Format', () => { + let convertHtml: Function; + + beforeEach(() => { + const source = new SourceFormat({}, jest.fn()); + + convertHtml = source.getConverterFor(HTML_CONTEXT_TYPE) as HtmlContextTypeConvert; + }); + + test('should use the text content type if a field is not passed', () => { + const hit = { + foo: 'bar', + number: 42, + hello: '

World

', + also: 'with "quotes" or \'single quotes\'', + }; + + expect(convertHtml(hit)).toBe( + '{"foo":"bar","number":42,"hello":"<h1>World</h1>","also":"with \\"quotes\\" or 'single quotes'"}' + ); + }); + + test('should render a description list if a field is passed', () => { + const hit = { + foo: 'bar', + number: 42, + hello: '

World

', + also: 'with "quotes" or \'single quotes\'', + }; + + expect( + convertHtml(hit, { field: 'field', indexPattern: { formatHit: (h: string) => h }, hit }) + ).toMatchInlineSnapshot( + `"
foo:
bar
number:
42
hello:

World

also:
with \\"quotes\\" or 'single quotes'
"` + ); + }); +}); diff --git a/src/plugins/field_formats/common/converters/source.tsx b/src/plugins/field_formats/common/converters/source.tsx new file mode 100644 index 0000000000000..110f866972727 --- /dev/null +++ b/src/plugins/field_formats/common/converters/source.tsx @@ -0,0 +1,75 @@ +/* + * 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 { KBN_FIELD_TYPES } from '@kbn/field-types'; +import React, { Fragment } from 'react'; +import ReactDOM from 'react-dom/server'; +import { escape, keys } from 'lodash'; +import { shortenDottedString } from '../utils'; +import { FieldFormat } from '../field_format'; +import { TextContextTypeConvert, HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; +import { FORMATS_UI_SETTINGS } from '../constants/ui_settings'; + +interface Props { + defPairs: Array<[string, string]>; +} +const TemplateComponent = ({ defPairs }: Props) => { + return ( +
+ {defPairs.map((pair, idx) => ( + +
+
{' '} + + ))} +
+ ); +}; + +/** @public */ +export class SourceFormat extends FieldFormat { + static id = FIELD_FORMAT_IDS._SOURCE; + static title = '_source'; + static fieldType = KBN_FIELD_TYPES._SOURCE; + + textConvert: TextContextTypeConvert = (value: string) => JSON.stringify(value); + + htmlConvert: HtmlContextTypeConvert = (value: string, options = {}) => { + const { field, hit, indexPattern } = options; + + // eslint-disable-next-line no-console + console.log('_source converter'); + if (!field) { + const converter = this.getConverterFor('text') as Function; + + return escape(converter(value)); + } + + const highlights: Record = (hit && hit.highlight) || {}; + // TODO: remove index pattern dependency + const formatted = hit ? indexPattern!.formatHit(hit) : {}; + const highlightPairs: Array<[string, string]> = []; + const sourcePairs: Array<[string, string]> = []; + const isShortDots = this.getConfig!(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE); + + keys(formatted).forEach((key) => { + const pairs = highlights[key] ? highlightPairs : sourcePairs; + const newField = isShortDots ? shortenDottedString(key) : key; + const val = formatted![key]; + pairs.push([newField as string, val]); + }, []); + + return ReactDOM.renderToStaticMarkup( + + ); + }; +} From 254d5caa0143c9a588af6e8c0427cf1ec7d28e56 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Fri, 8 Oct 2021 17:44:30 +0300 Subject: [PATCH 04/24] [Discover] move truncate by height to discover settings category, apply css via emotion --- docs/management/advanced-options.asciidoc | 8 ++--- src/core/server/ui_settings/settings/index.ts | 2 -- .../server/ui_settings/settings/misc.test.ts | 31 ------------------ src/core/server/ui_settings/settings/misc.ts | 31 ------------------ src/plugins/discover/common/index.ts | 1 + .../main/components/doc_table/_doc_table.scss | 4 --- .../doc_table/doc_table_wrapper.tsx | 22 +++++++++++++ .../lib/formatters/row_formatter.tsx | 2 +- .../lib/formatters/source_formatter.tsx | 2 +- src/plugins/discover/server/ui_settings.ts | 13 ++++++++ .../common/converters/source.test.ts | 2 +- .../common/converters/source.tsx | 4 +-- src/plugins/kibana_legacy/public/plugin.ts | 6 ++-- .../public/utils/inject_header_style.ts | 32 ------------------- .../server/collectors/management/schema.ts | 2 +- .../server/collectors/management/types.ts | 2 +- src/plugins/telemetry/schema/oss_plugins.json | 2 +- 17 files changed, 49 insertions(+), 117 deletions(-) delete mode 100644 src/core/server/ui_settings/settings/misc.test.ts delete mode 100644 src/core/server/ui_settings/settings/misc.ts delete mode 100644 src/plugins/kibana_legacy/public/utils/inject_header_style.ts diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index 6fd83e8af3d15..aa26bc4bff4e3 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -204,10 +204,6 @@ The default refresh interval for the time filter. Example: [[timepicker-timedefaults]]`timepicker:timeDefaults`:: The default selection in the time filter. -[[truncate-maxheight]]`truncate:maxHeight`:: -The maximum height that a cell occupies in a table. Set to 0 to disable -truncation. - [float] [[presentation-labs]] ==== Presentation Labs @@ -316,6 +312,10 @@ When enabled, displays multi-fields in the expanded document view. [[discover-sort-defaultorder]]`discover:sort:defaultOrder`:: The default sort direction for time-based index patterns. +[[discover-truncate-maxheight]]`discover:truncate:maxHeight`:: +The maximum height that a cell occupies in a classic table. Set to 0 to disable +truncation. + [[doctable-hidetimecolumn]]`doc_table:hideTimeColumn`:: Hides the "Time" column in *Discover* and in all saved searches on dashboards. diff --git a/src/core/server/ui_settings/settings/index.ts b/src/core/server/ui_settings/settings/index.ts index 944ada3a63e4f..fdc66d8e77a8a 100644 --- a/src/core/server/ui_settings/settings/index.ts +++ b/src/core/server/ui_settings/settings/index.ts @@ -9,7 +9,6 @@ import { UiSettingsParams } from '../../../types'; import { getAccessibilitySettings } from './accessibility'; import { getDateFormatSettings } from './date_formats'; -import { getMiscUiSettings } from './misc'; import { getNavigationSettings } from './navigation'; import { getNotificationsSettings } from './notifications'; import { getThemeSettings } from './theme'; @@ -25,7 +24,6 @@ export const getCoreSettings = ( return { ...getAccessibilitySettings(), ...getDateFormatSettings(), - ...getMiscUiSettings(), ...getNavigationSettings(), ...getNotificationsSettings(), ...getThemeSettings(options), diff --git a/src/core/server/ui_settings/settings/misc.test.ts b/src/core/server/ui_settings/settings/misc.test.ts deleted file mode 100644 index 7b6788664c997..0000000000000 --- a/src/core/server/ui_settings/settings/misc.test.ts +++ /dev/null @@ -1,31 +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 { UiSettingsParams } from '../../../types'; -import { getMiscUiSettings } from './misc'; - -describe('misc settings', () => { - const miscSettings = getMiscUiSettings(); - - const getValidationFn = (setting: UiSettingsParams) => (value: any) => - setting.schema.validate(value); - - describe('truncate:maxHeight', () => { - const validate = getValidationFn(miscSettings['truncate:maxHeight']); - - it('should only accept positive numeric values', () => { - expect(() => validate(127)).not.toThrow(); - expect(() => validate(-12)).toThrowErrorMatchingInlineSnapshot( - `"Value must be equal to or greater than [0]."` - ); - expect(() => validate('foo')).toThrowErrorMatchingInlineSnapshot( - `"expected value of type [number] but got [string]"` - ); - }); - }); -}); diff --git a/src/core/server/ui_settings/settings/misc.ts b/src/core/server/ui_settings/settings/misc.ts deleted file mode 100644 index cd9e43400d3c9..0000000000000 --- a/src/core/server/ui_settings/settings/misc.ts +++ /dev/null @@ -1,31 +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 { i18n } from '@kbn/i18n'; -import { schema } from '@kbn/config-schema'; -import { UiSettingsParams } from '../types'; - -export const getMiscUiSettings = (): Record => { - return { - 'truncate:maxHeight': { - name: i18n.translate('core.ui_settings.params.maxCellHeightTitle', { - defaultMessage: 'Maximum table cell height', - }), - value: 115, - description: i18n.translate('core.ui_settings.params.maxCellHeightText', { - defaultMessage: - 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', - }), - schema: schema.number({ min: 0 }), - }, - buildNum: { - readonly: true, - schema: schema.maybe(schema.number()), - }, - }; -}; diff --git a/src/plugins/discover/common/index.ts b/src/plugins/discover/common/index.ts index b30fcf972eda5..61dcc35024377 100644 --- a/src/plugins/discover/common/index.ts +++ b/src/plugins/discover/common/index.ts @@ -20,4 +20,5 @@ export const MODIFY_COLUMNS_ON_SWITCH = 'discover:modifyColumnsOnSwitch'; export const SEARCH_FIELDS_FROM_SOURCE = 'discover:searchFieldsFromSource'; export const MAX_DOC_FIELDS_DISPLAYED = 'discover:maxDocFieldsDisplayed'; export const SHOW_MULTIFIELDS = 'discover:showMultiFields'; +export const TRUNCATE_MAX_HEIGHT = 'discover:truncate:maxHeight'; export const SEARCH_EMBEDDABLE_TYPE = 'search'; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/_doc_table.scss b/src/plugins/discover/public/application/apps/main/components/doc_table/_doc_table.scss index d19a1fd042069..164b61d42df19 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/_doc_table.scss +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/_doc_table.scss @@ -103,10 +103,6 @@ text-align: center; } -.truncate-by-height { - overflow: hidden; -} - .table { // Nesting .table { diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx index 7a88d965d673f..2ff5356970a8b 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx @@ -10,6 +10,7 @@ import React, { forwardRef, useCallback, useMemo } from 'react'; import { EuiIcon, EuiSpacer, EuiText } from '@elastic/eui'; import type { IndexPattern, IndexPatternField } from 'src/plugins/data/common'; import { FormattedMessage } from '@kbn/i18n/react'; +import { css, Global } from '@emotion/react'; import { TableHeader } from './components/table_header/table_header'; import { FORMATS_UI_SETTINGS } from '../../../../../../../field_formats/common'; import { @@ -17,6 +18,7 @@ import { SAMPLE_SIZE_SETTING, SHOW_MULTIFIELDS, SORT_DEFAULT_ORDER_SETTING, + TRUNCATE_MAX_HEIGHT, } from '../../../../../../common'; import { getServices } from '../../../../../kibana_services'; import { SortOrder } from './components/table_header/helpers'; @@ -99,6 +101,8 @@ export interface DocTableWrapperProps extends DocTableProps { render: (params: DocTableRenderProps) => JSX.Element; } +const TRUNCATE_GRADIENT_HEIGHT = 15; + const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); export const DocTableWrapper = forwardRef( @@ -128,6 +132,7 @@ export const DocTableWrapper = forwardRef( isShortDots, sampleSize, showMultiFields, + maxHeight, filterManager, addBasePath, ] = useMemo(() => { @@ -138,6 +143,7 @@ export const DocTableWrapper = forwardRef( services.uiSettings.get(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE), services.uiSettings.get(SAMPLE_SIZE_SETTING, 500), services.uiSettings.get(SHOW_MULTIFIELDS, false), + services.uiSettings.get(TRUNCATE_MAX_HEIGHT), services.filterManager, services.addBasePath, ]; @@ -239,6 +245,22 @@ export const DocTableWrapper = forwardRef( data-render-complete={!isLoading} ref={ref as React.MutableRefObject} > + {maxHeight !== 0 && ( + 0 ? `${maxHeight}px !important` : 'none'}; + display: inline-block; + } + .truncate-by-height:before { + top: ${maxHeight > 0 + ? maxHeight - TRUNCATE_GRADIENT_HEIGHT + : TRUNCATE_GRADIENT_HEIGHT * -1}px; + } + `} + /> + )} {rows.length !== 0 && render({ columnLength: columns.length, diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx index e3cc3f2e18c09..5edba742e93af 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx @@ -18,7 +18,7 @@ interface Props { } const TemplateComponent = ({ defPairs }: Props) => { return ( -
+
{defPairs.map((pair, idx) => (
{pair[0]}:
diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx index 31f95cafe631a..a0c3efe5c5e4a 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx @@ -18,7 +18,7 @@ interface Props { const TemplateComponent = ({ defPairs }: Props) => { return ( -
+
{defPairs.map((pair, idx) => (
Record = () => ({ @@ -220,4 +221,16 @@ export const getUiSettings: () => Record = () => ({ category: ['discover'], schema: schema.boolean(), }, + [TRUNCATE_MAX_HEIGHT]: { + name: i18n.translate('core.ui_settings.params.maxCellHeightTitle', { + defaultMessage: 'Maximum table cell height', + }), + value: 115, + description: i18n.translate('core.ui_settings.params.maxCellHeightText', { + defaultMessage: + 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', + }), + schema: schema.number({ min: 0 }), + category: ['discover'], + }, }); diff --git a/src/plugins/field_formats/common/converters/source.test.ts b/src/plugins/field_formats/common/converters/source.test.ts index 298c93dac8c4e..d26849d91c233 100644 --- a/src/plugins/field_formats/common/converters/source.test.ts +++ b/src/plugins/field_formats/common/converters/source.test.ts @@ -43,7 +43,7 @@ describe('Source Format', () => { expect( convertHtml(hit, { field: 'field', indexPattern: { formatHit: (h: string) => h }, hit }) ).toMatchInlineSnapshot( - `"
foo:
bar
number:
42
hello:

World

also:
with \\"quotes\\" or 'single quotes'
"` + `"
foo:
bar
number:
42
hello:

World

also:
with \\"quotes\\" or 'single quotes'
"` ); }); }); diff --git a/src/plugins/field_formats/common/converters/source.tsx b/src/plugins/field_formats/common/converters/source.tsx index 110f866972727..7d2da7831cf4f 100644 --- a/src/plugins/field_formats/common/converters/source.tsx +++ b/src/plugins/field_formats/common/converters/source.tsx @@ -20,7 +20,7 @@ interface Props { } const TemplateComponent = ({ defPairs }: Props) => { return ( -
+
{defPairs.map((pair, idx) => (
{ const { field, hit, indexPattern } = options; - // eslint-disable-next-line no-console - console.log('_source converter'); if (!field) { const converter = this.getConverterFor('text') as Function; diff --git a/src/plugins/kibana_legacy/public/plugin.ts b/src/plugins/kibana_legacy/public/plugin.ts index ac78e8cac4f07..a154770bbfffd 100644 --- a/src/plugins/kibana_legacy/public/plugin.ts +++ b/src/plugins/kibana_legacy/public/plugin.ts @@ -6,16 +6,14 @@ * Side Public License, v 1. */ -import { CoreStart, CoreSetup } from 'kibana/public'; -import { injectHeaderStyle } from './utils/inject_header_style'; +import type { CoreSetup } from 'kibana/public'; export class KibanaLegacyPlugin { public setup(core: CoreSetup<{}, KibanaLegacyStart>) { return {}; } - public start({ uiSettings }: CoreStart) { - injectHeaderStyle(uiSettings); + public start() { return { /** * Loads the font-awesome icon font. Should be removed once the last consumer has migrated to EUI diff --git a/src/plugins/kibana_legacy/public/utils/inject_header_style.ts b/src/plugins/kibana_legacy/public/utils/inject_header_style.ts deleted file mode 100644 index 967aa2232838e..0000000000000 --- a/src/plugins/kibana_legacy/public/utils/inject_header_style.ts +++ /dev/null @@ -1,32 +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 { IUiSettingsClient } from 'kibana/public'; - -export function buildCSS(maxHeight = 0, truncateGradientHeight = 15) { - return ` -.truncate-by-height { - max-height: ${maxHeight > 0 ? `${maxHeight}px !important` : 'none'}; - display: inline-block; -} -.truncate-by-height:before { - top: ${maxHeight > 0 ? maxHeight - truncateGradientHeight : truncateGradientHeight * -1}px; -} -`; -} - -export function injectHeaderStyle(uiSettings: IUiSettingsClient) { - const style = document.createElement('style'); - style.setAttribute('id', 'style-compile'); - document.getElementsByTagName('head')[0].appendChild(style); - - uiSettings.get$('truncate:maxHeight').subscribe((value: number) => { - // eslint-disable-next-line no-unsanitized/property - style.innerHTML = buildCSS(value); - }); -} diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index a8a391995b005..a810b0cf55380 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -220,7 +220,7 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, }, - 'truncate:maxHeight': { + 'discover:truncate:maxHeight': { type: 'long', _meta: { description: 'Non-default value of setting.' }, }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 7ea80ffb77dda..fa8a876c48633 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -77,7 +77,7 @@ export interface UsageStats { 'fileUpload:maxFileSize': string; 'ml:anomalyDetection:results:enableTimeDefaults': boolean; 'ml:anomalyDetection:results:timeDefaults': string; - 'truncate:maxHeight': number; + 'discover:truncate:maxHeight': number; 'timepicker:timeDefaults': string; 'timepicker:refreshIntervalDefaults': string; 'timepicker:quickRanges': string; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index c6724056f77a5..e9b4090136701 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -7344,7 +7344,7 @@ "description": "Non-default value of setting." } }, - "truncate:maxHeight": { + "discover:truncate:maxHeight": { "type": "long", "_meta": { "description": "Non-default value of setting." From 5a201c41ae9967f41eff6e6f3996b5674db5f2ea Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Mon, 11 Oct 2021 14:08:56 +0300 Subject: [PATCH 05/24] [Discover] improve code readability, fix i18n --- .../server/ui_settings/settings/index.test.ts | 2 - .../doc_table/doc_table_wrapper.tsx | 60 ++++++++++--------- src/plugins/discover/server/ui_settings.ts | 2 +- .../translations/translations/ja-JP.json | 2 +- .../translations/translations/zh-CN.json | 2 +- 5 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/core/server/ui_settings/settings/index.test.ts b/src/core/server/ui_settings/settings/index.test.ts index a4a66a96d3a2b..799a5a3c7107d 100644 --- a/src/core/server/ui_settings/settings/index.test.ts +++ b/src/core/server/ui_settings/settings/index.test.ts @@ -8,7 +8,6 @@ import { getAccessibilitySettings } from './accessibility'; import { getDateFormatSettings } from './date_formats'; -import { getMiscUiSettings } from './misc'; import { getNavigationSettings } from './navigation'; import { getNotificationsSettings } from './notifications'; import { getThemeSettings } from './theme'; @@ -21,7 +20,6 @@ describe('getCoreSettings', () => { const summedLength = [ getAccessibilitySettings(), getDateFormatSettings(), - getMiscUiSettings(), getNavigationSettings(), getNotificationsSettings(), getThemeSettings(), diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx index 2ff5356970a8b..fd65451ac6040 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx @@ -235,6 +235,36 @@ export const DocTableWrapper = forwardRef( ] ); + const truncateStyles = ( + 0 ? `${maxHeight}px !important` : 'none'}; + display: inline-block; + } + .truncate-by-height:before { + top: ${maxHeight > 0 + ? maxHeight - TRUNCATE_GRADIENT_HEIGHT + : TRUNCATE_GRADIENT_HEIGHT * -1}px; + } + `} + /> + ); + + const noResultsError = ( +
+ + + + + +
+ ); + return (
} > - {maxHeight !== 0 && ( - 0 ? `${maxHeight}px !important` : 'none'}; - display: inline-block; - } - .truncate-by-height:before { - top: ${maxHeight > 0 - ? maxHeight - TRUNCATE_GRADIENT_HEIGHT - : TRUNCATE_GRADIENT_HEIGHT * -1}px; - } - `} - /> - )} + {maxHeight !== 0 && truncateStyles} {rows.length !== 0 && render({ columnLength: columns.length, @@ -270,18 +285,7 @@ export const DocTableWrapper = forwardRef( renderHeader, renderRows, })} - {!rows.length && ( -
- - - - - -
- )} + {!rows.length && noResultsError}
); } diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index c0314cb9332ce..1833f94d8a570 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -222,7 +222,7 @@ export const getUiSettings: () => Record = () => ({ schema: schema.boolean(), }, [TRUNCATE_MAX_HEIGHT]: { - name: i18n.translate('core.ui_settings.params.maxCellHeightTitle', { + name: i18n.translate('discover.advancedSettings.discover.maxCellHeightTitle', { defaultMessage: 'Maximum table cell height', }), value: 115, diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index f36f3abe66a4c..d6c770ee7d54c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1332,7 +1332,6 @@ "core.ui_settings.params.disableAnimationsText": "Kibana UIの不要なアニメーションをオフにします。変更を適用するにはページを更新してください。", "core.ui_settings.params.disableAnimationsTitle": "アニメーションを無効にする", "core.ui_settings.params.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します", - "core.ui_settings.params.maxCellHeightTitle": "表のセルの高さの上限", "core.ui_settings.params.notifications.banner.markdownLinkText": "マークダウン対応", "core.ui_settings.params.notifications.bannerLifetimeText": "バナー通知が画面に表示される時間(ミリ秒単位)です。", "core.ui_settings.params.notifications.bannerLifetimeTitle": "バナー通知時間", @@ -2329,6 +2328,7 @@ "discover.advancedSettings.discover.modifyColumnsOnSwitchText": "新しいインデックスパターンで使用できない列を削除します。", "discover.advancedSettings.discover.modifyColumnsOnSwitchTitle": "インデックスパターンを変更するときに列を修正", "discover.advancedSettings.discover.multiFieldsLinkText": "マルチフィールド", + "discover.advancedSettings.discover.maxCellHeightTitle": "表のセルの高さの上限", "discover.advancedSettings.discover.readFieldsFromSource": "_sourceからフィールドを読み取る", "discover.advancedSettings.discover.readFieldsFromSourceDescription": "有効にすると、「_source」から直接ドキュメントを読み込みます。これはまもなく廃止される予定です。無効にすると、上位レベルの検索サービスで新しいフィールドAPI経由でフィールドを取得します。", "discover.advancedSettings.discover.showMultifields": "マルチフィールドを表示", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 11b951b97ae05..af2def110be72 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1350,7 +1350,6 @@ "core.ui_settings.params.disableAnimationsText": "在 Kibana UI 中关闭所有不必要的动画。刷新页面可应用所做的更改。", "core.ui_settings.params.disableAnimationsTitle": "禁用动画", "core.ui_settings.params.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断", - "core.ui_settings.params.maxCellHeightTitle": "最大表单元格高度", "core.ui_settings.params.notifications.banner.markdownLinkText": "Markdown 受支持", "core.ui_settings.params.notifications.bannerLifetimeText": "在屏幕上显示横幅通知的时间(毫秒)。", "core.ui_settings.params.notifications.bannerLifetimeTitle": "横幅通知生存时间", @@ -2353,6 +2352,7 @@ "discover.advancedSettings.discover.modifyColumnsOnSwitchText": "移除新索引模式中不存在的列。", "discover.advancedSettings.discover.modifyColumnsOnSwitchTitle": "更改索引模式时修改列", "discover.advancedSettings.discover.multiFieldsLinkText": "多字段", + "discover.advancedSettings.discover.maxCellHeightTitle": "最大表单元格高度", "discover.advancedSettings.discover.readFieldsFromSource": "从 _source 读取字段", "discover.advancedSettings.discover.readFieldsFromSourceDescription": "启用后,将直接从 `_source` 加载文档。这很快将被弃用。禁用后,将通过高级别搜索服务中的新字段 API 检索字段。", "discover.advancedSettings.discover.showMultifields": "显示多字段", From a610b677961b09f5813969f35ec4435460ce5dea Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Mon, 11 Oct 2021 14:27:26 +0300 Subject: [PATCH 06/24] [Discover] fix remaining i18n --- src/plugins/discover/server/ui_settings.ts | 2 +- x-pack/plugins/translations/translations/ja-JP.json | 2 +- x-pack/plugins/translations/translations/zh-CN.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index 1833f94d8a570..97faa844c6e55 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -226,7 +226,7 @@ export const getUiSettings: () => Record = () => ({ defaultMessage: 'Maximum table cell height', }), value: 115, - description: i18n.translate('core.ui_settings.params.maxCellHeightText', { + description: i18n.translate('discover.advancedSettings.maxCellHeightText', { defaultMessage: 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', }), diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d6c770ee7d54c..b694b1380ffe6 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1331,7 +1331,6 @@ "core.ui_settings.params.defaultRoute.defaultRouteTitle": "デフォルトのルート", "core.ui_settings.params.disableAnimationsText": "Kibana UIの不要なアニメーションをオフにします。変更を適用するにはページを更新してください。", "core.ui_settings.params.disableAnimationsTitle": "アニメーションを無効にする", - "core.ui_settings.params.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します", "core.ui_settings.params.notifications.banner.markdownLinkText": "マークダウン対応", "core.ui_settings.params.notifications.bannerLifetimeText": "バナー通知が画面に表示される時間(ミリ秒単位)です。", "core.ui_settings.params.notifications.bannerLifetimeTitle": "バナー通知時間", @@ -2341,6 +2340,7 @@ "discover.advancedSettings.fieldsPopularLimitTitle": "頻繁に使用されるフィールドの制限", "discover.advancedSettings.maxDocFieldsDisplayedText": "ドキュメント列でレンダリングされたフィールドの最大数", "discover.advancedSettings.maxDocFieldsDisplayedTitle": "表示される最大ドキュメントフィールド数", + "discover.advancedSettings.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します", "discover.advancedSettings.sampleSizeText": "表に表示する行数です", "discover.advancedSettings.sampleSizeTitle": "行数", "discover.advancedSettings.searchOnPageLoadText": "Discover の最初の読み込み時に検索を実行するかを制御します。この設定は、保存された検索の読み込み時には影響しません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index af2def110be72..a78b1e9384638 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1349,7 +1349,6 @@ "core.ui_settings.params.defaultRoute.defaultRouteTitle": "默认路由", "core.ui_settings.params.disableAnimationsText": "在 Kibana UI 中关闭所有不必要的动画。刷新页面可应用所做的更改。", "core.ui_settings.params.disableAnimationsTitle": "禁用动画", - "core.ui_settings.params.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断", "core.ui_settings.params.notifications.banner.markdownLinkText": "Markdown 受支持", "core.ui_settings.params.notifications.bannerLifetimeText": "在屏幕上显示横幅通知的时间(毫秒)。", "core.ui_settings.params.notifications.bannerLifetimeTitle": "横幅通知生存时间", @@ -2365,6 +2364,7 @@ "discover.advancedSettings.fieldsPopularLimitTitle": "常见字段限制", "discover.advancedSettings.maxDocFieldsDisplayedText": "在文档列中渲染的最大字段数目", "discover.advancedSettings.maxDocFieldsDisplayedTitle": "显示的最大文档字段数", + "discover.advancedSettings.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断", "discover.advancedSettings.sampleSizeText": "要在表中显示的行数目", "discover.advancedSettings.sampleSizeTitle": "行数目", "discover.advancedSettings.searchOnPageLoadText": "控制在 Discover 首次加载时是否执行搜索。加载已保存搜索时,此设置无效。", From 8b163ca8ef438ddb60e09fef29ab158e340a3e39 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Mon, 11 Oct 2021 16:29:16 +0300 Subject: [PATCH 07/24] [Discover] fix unit tests --- .../main/components/doc_table/components/table_row.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.test.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.test.tsx index 887564168ac85..7cf6c0f4b59e5 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.test.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.test.tsx @@ -16,8 +16,8 @@ import { indexPatternWithTimefieldMock } from '../../../../../../__mocks__/index import { uiSettingsMock } from '../../../../../../__mocks__/ui_settings'; import { DocViewsRegistry } from '../../../../../doc_views/doc_views_registry'; -jest.mock('../lib/row_formatter', () => { - const originalModule = jest.requireActual('../lib/row_formatter'); +jest.mock('../lib/formatters/row_formatter', () => { + const originalModule = jest.requireActual('../lib/formatters/row_formatter'); return { ...originalModule, formatRow: () => mocked_document_cell, From 57ff5822bc422016bb25ec2ebc162378d7a9bbb9 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Tue, 12 Oct 2021 14:56:15 +0300 Subject: [PATCH 08/24] [Discover] return truncate-by-height setting to general --- docs/management/advanced-options.asciidoc | 8 ++--- .../server/ui_settings/settings/index.test.ts | 2 ++ src/core/server/ui_settings/settings/index.ts | 2 ++ .../server/ui_settings/settings/misc.test.ts | 31 ++++++++++++++++++ src/core/server/ui_settings/settings/misc.ts | 32 +++++++++++++++++++ src/plugins/discover/common/index.ts | 2 +- src/plugins/discover/server/ui_settings.ts | 13 -------- .../server/collectors/management/schema.ts | 2 +- .../server/collectors/management/types.ts | 2 +- src/plugins/telemetry/schema/oss_plugins.json | 2 +- .../translations/translations/ja-JP.json | 4 +-- .../translations/translations/zh-CN.json | 4 +-- 12 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 src/core/server/ui_settings/settings/misc.test.ts create mode 100644 src/core/server/ui_settings/settings/misc.ts diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index aa26bc4bff4e3..6fd83e8af3d15 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -204,6 +204,10 @@ The default refresh interval for the time filter. Example: [[timepicker-timedefaults]]`timepicker:timeDefaults`:: The default selection in the time filter. +[[truncate-maxheight]]`truncate:maxHeight`:: +The maximum height that a cell occupies in a table. Set to 0 to disable +truncation. + [float] [[presentation-labs]] ==== Presentation Labs @@ -312,10 +316,6 @@ When enabled, displays multi-fields in the expanded document view. [[discover-sort-defaultorder]]`discover:sort:defaultOrder`:: The default sort direction for time-based index patterns. -[[discover-truncate-maxheight]]`discover:truncate:maxHeight`:: -The maximum height that a cell occupies in a classic table. Set to 0 to disable -truncation. - [[doctable-hidetimecolumn]]`doc_table:hideTimeColumn`:: Hides the "Time" column in *Discover* and in all saved searches on dashboards. diff --git a/src/core/server/ui_settings/settings/index.test.ts b/src/core/server/ui_settings/settings/index.test.ts index 799a5a3c7107d..a4a66a96d3a2b 100644 --- a/src/core/server/ui_settings/settings/index.test.ts +++ b/src/core/server/ui_settings/settings/index.test.ts @@ -8,6 +8,7 @@ import { getAccessibilitySettings } from './accessibility'; import { getDateFormatSettings } from './date_formats'; +import { getMiscUiSettings } from './misc'; import { getNavigationSettings } from './navigation'; import { getNotificationsSettings } from './notifications'; import { getThemeSettings } from './theme'; @@ -20,6 +21,7 @@ describe('getCoreSettings', () => { const summedLength = [ getAccessibilitySettings(), getDateFormatSettings(), + getMiscUiSettings(), getNavigationSettings(), getNotificationsSettings(), getThemeSettings(), diff --git a/src/core/server/ui_settings/settings/index.ts b/src/core/server/ui_settings/settings/index.ts index fdc66d8e77a8a..944ada3a63e4f 100644 --- a/src/core/server/ui_settings/settings/index.ts +++ b/src/core/server/ui_settings/settings/index.ts @@ -9,6 +9,7 @@ import { UiSettingsParams } from '../../../types'; import { getAccessibilitySettings } from './accessibility'; import { getDateFormatSettings } from './date_formats'; +import { getMiscUiSettings } from './misc'; import { getNavigationSettings } from './navigation'; import { getNotificationsSettings } from './notifications'; import { getThemeSettings } from './theme'; @@ -24,6 +25,7 @@ export const getCoreSettings = ( return { ...getAccessibilitySettings(), ...getDateFormatSettings(), + ...getMiscUiSettings(), ...getNavigationSettings(), ...getNotificationsSettings(), ...getThemeSettings(options), diff --git a/src/core/server/ui_settings/settings/misc.test.ts b/src/core/server/ui_settings/settings/misc.test.ts new file mode 100644 index 0000000000000..7b6788664c997 --- /dev/null +++ b/src/core/server/ui_settings/settings/misc.test.ts @@ -0,0 +1,31 @@ +/* + * 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 { UiSettingsParams } from '../../../types'; +import { getMiscUiSettings } from './misc'; + +describe('misc settings', () => { + const miscSettings = getMiscUiSettings(); + + const getValidationFn = (setting: UiSettingsParams) => (value: any) => + setting.schema.validate(value); + + describe('truncate:maxHeight', () => { + const validate = getValidationFn(miscSettings['truncate:maxHeight']); + + it('should only accept positive numeric values', () => { + expect(() => validate(127)).not.toThrow(); + expect(() => validate(-12)).toThrowErrorMatchingInlineSnapshot( + `"Value must be equal to or greater than [0]."` + ); + expect(() => validate('foo')).toThrowErrorMatchingInlineSnapshot( + `"expected value of type [number] but got [string]"` + ); + }); + }); +}); diff --git a/src/core/server/ui_settings/settings/misc.ts b/src/core/server/ui_settings/settings/misc.ts new file mode 100644 index 0000000000000..2b61a48de4de7 --- /dev/null +++ b/src/core/server/ui_settings/settings/misc.ts @@ -0,0 +1,32 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { schema } from '@kbn/config-schema'; +import { UiSettingsParams } from '../types'; + +export const getMiscUiSettings = (): Record => { + return { + 'truncate:maxHeight': { + name: i18n.translate('discover.advancedSettings.discover.maxCellHeightTitle', { + defaultMessage: 'Maximum table cell height', + }), + value: 115, + description: i18n.translate('discover.advancedSettings.maxCellHeightText', { + defaultMessage: + 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', + }), + schema: schema.number({ min: 0 }), + category: ['discover'], + }, + buildNum: { + readonly: true, + schema: schema.maybe(schema.number()), + }, + }; +}; diff --git a/src/plugins/discover/common/index.ts b/src/plugins/discover/common/index.ts index 61dcc35024377..b64b18b21e3d6 100644 --- a/src/plugins/discover/common/index.ts +++ b/src/plugins/discover/common/index.ts @@ -20,5 +20,5 @@ export const MODIFY_COLUMNS_ON_SWITCH = 'discover:modifyColumnsOnSwitch'; export const SEARCH_FIELDS_FROM_SOURCE = 'discover:searchFieldsFromSource'; export const MAX_DOC_FIELDS_DISPLAYED = 'discover:maxDocFieldsDisplayed'; export const SHOW_MULTIFIELDS = 'discover:showMultiFields'; -export const TRUNCATE_MAX_HEIGHT = 'discover:truncate:maxHeight'; +export const TRUNCATE_MAX_HEIGHT = 'truncate:maxHeight'; export const SEARCH_EMBEDDABLE_TYPE = 'search'; diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index 97faa844c6e55..aa1b44da12bfc 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -26,7 +26,6 @@ import { SEARCH_FIELDS_FROM_SOURCE, MAX_DOC_FIELDS_DISPLAYED, SHOW_MULTIFIELDS, - TRUNCATE_MAX_HEIGHT, } from '../common'; export const getUiSettings: () => Record = () => ({ @@ -221,16 +220,4 @@ export const getUiSettings: () => Record = () => ({ category: ['discover'], schema: schema.boolean(), }, - [TRUNCATE_MAX_HEIGHT]: { - name: i18n.translate('discover.advancedSettings.discover.maxCellHeightTitle', { - defaultMessage: 'Maximum table cell height', - }), - value: 115, - description: i18n.translate('discover.advancedSettings.maxCellHeightText', { - defaultMessage: - 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', - }), - schema: schema.number({ min: 0 }), - category: ['discover'], - }, }); diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index a810b0cf55380..a8a391995b005 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -220,7 +220,7 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, }, - 'discover:truncate:maxHeight': { + 'truncate:maxHeight': { type: 'long', _meta: { description: 'Non-default value of setting.' }, }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index fa8a876c48633..7ea80ffb77dda 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -77,7 +77,7 @@ export interface UsageStats { 'fileUpload:maxFileSize': string; 'ml:anomalyDetection:results:enableTimeDefaults': boolean; 'ml:anomalyDetection:results:timeDefaults': string; - 'discover:truncate:maxHeight': number; + 'truncate:maxHeight': number; 'timepicker:timeDefaults': string; 'timepicker:refreshIntervalDefaults': string; 'timepicker:quickRanges': string; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index e9b4090136701..c6724056f77a5 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -7344,7 +7344,7 @@ "description": "Non-default value of setting." } }, - "discover:truncate:maxHeight": { + "truncate:maxHeight": { "type": "long", "_meta": { "description": "Non-default value of setting." diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index b694b1380ffe6..f36f3abe66a4c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1331,6 +1331,8 @@ "core.ui_settings.params.defaultRoute.defaultRouteTitle": "デフォルトのルート", "core.ui_settings.params.disableAnimationsText": "Kibana UIの不要なアニメーションをオフにします。変更を適用するにはページを更新してください。", "core.ui_settings.params.disableAnimationsTitle": "アニメーションを無効にする", + "core.ui_settings.params.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します", + "core.ui_settings.params.maxCellHeightTitle": "表のセルの高さの上限", "core.ui_settings.params.notifications.banner.markdownLinkText": "マークダウン対応", "core.ui_settings.params.notifications.bannerLifetimeText": "バナー通知が画面に表示される時間(ミリ秒単位)です。", "core.ui_settings.params.notifications.bannerLifetimeTitle": "バナー通知時間", @@ -2327,7 +2329,6 @@ "discover.advancedSettings.discover.modifyColumnsOnSwitchText": "新しいインデックスパターンで使用できない列を削除します。", "discover.advancedSettings.discover.modifyColumnsOnSwitchTitle": "インデックスパターンを変更するときに列を修正", "discover.advancedSettings.discover.multiFieldsLinkText": "マルチフィールド", - "discover.advancedSettings.discover.maxCellHeightTitle": "表のセルの高さの上限", "discover.advancedSettings.discover.readFieldsFromSource": "_sourceからフィールドを読み取る", "discover.advancedSettings.discover.readFieldsFromSourceDescription": "有効にすると、「_source」から直接ドキュメントを読み込みます。これはまもなく廃止される予定です。無効にすると、上位レベルの検索サービスで新しいフィールドAPI経由でフィールドを取得します。", "discover.advancedSettings.discover.showMultifields": "マルチフィールドを表示", @@ -2340,7 +2341,6 @@ "discover.advancedSettings.fieldsPopularLimitTitle": "頻繁に使用されるフィールドの制限", "discover.advancedSettings.maxDocFieldsDisplayedText": "ドキュメント列でレンダリングされたフィールドの最大数", "discover.advancedSettings.maxDocFieldsDisplayedTitle": "表示される最大ドキュメントフィールド数", - "discover.advancedSettings.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します", "discover.advancedSettings.sampleSizeText": "表に表示する行数です", "discover.advancedSettings.sampleSizeTitle": "行数", "discover.advancedSettings.searchOnPageLoadText": "Discover の最初の読み込み時に検索を実行するかを制御します。この設定は、保存された検索の読み込み時には影響しません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index a78b1e9384638..11b951b97ae05 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1349,6 +1349,8 @@ "core.ui_settings.params.defaultRoute.defaultRouteTitle": "默认路由", "core.ui_settings.params.disableAnimationsText": "在 Kibana UI 中关闭所有不必要的动画。刷新页面可应用所做的更改。", "core.ui_settings.params.disableAnimationsTitle": "禁用动画", + "core.ui_settings.params.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断", + "core.ui_settings.params.maxCellHeightTitle": "最大表单元格高度", "core.ui_settings.params.notifications.banner.markdownLinkText": "Markdown 受支持", "core.ui_settings.params.notifications.bannerLifetimeText": "在屏幕上显示横幅通知的时间(毫秒)。", "core.ui_settings.params.notifications.bannerLifetimeTitle": "横幅通知生存时间", @@ -2351,7 +2353,6 @@ "discover.advancedSettings.discover.modifyColumnsOnSwitchText": "移除新索引模式中不存在的列。", "discover.advancedSettings.discover.modifyColumnsOnSwitchTitle": "更改索引模式时修改列", "discover.advancedSettings.discover.multiFieldsLinkText": "多字段", - "discover.advancedSettings.discover.maxCellHeightTitle": "最大表单元格高度", "discover.advancedSettings.discover.readFieldsFromSource": "从 _source 读取字段", "discover.advancedSettings.discover.readFieldsFromSourceDescription": "启用后,将直接从 `_source` 加载文档。这很快将被弃用。禁用后,将通过高级别搜索服务中的新字段 API 检索字段。", "discover.advancedSettings.discover.showMultifields": "显示多字段", @@ -2364,7 +2365,6 @@ "discover.advancedSettings.fieldsPopularLimitTitle": "常见字段限制", "discover.advancedSettings.maxDocFieldsDisplayedText": "在文档列中渲染的最大字段数目", "discover.advancedSettings.maxDocFieldsDisplayedTitle": "显示的最大文档字段数", - "discover.advancedSettings.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断", "discover.advancedSettings.sampleSizeText": "要在表中显示的行数目", "discover.advancedSettings.sampleSizeTitle": "行数目", "discover.advancedSettings.searchOnPageLoadText": "控制在 Discover 首次加载时是否执行搜索。加载已保存搜索时,此设置无效。", From 2dabce6efc7e8643d223c87a204abc67402f162f Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Tue, 12 Oct 2021 14:58:18 +0300 Subject: [PATCH 09/24] [Discover] return i18n naming --- src/core/server/ui_settings/settings/misc.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/server/ui_settings/settings/misc.ts b/src/core/server/ui_settings/settings/misc.ts index 2b61a48de4de7..cd9e43400d3c9 100644 --- a/src/core/server/ui_settings/settings/misc.ts +++ b/src/core/server/ui_settings/settings/misc.ts @@ -13,16 +13,15 @@ import { UiSettingsParams } from '../types'; export const getMiscUiSettings = (): Record => { return { 'truncate:maxHeight': { - name: i18n.translate('discover.advancedSettings.discover.maxCellHeightTitle', { + name: i18n.translate('core.ui_settings.params.maxCellHeightTitle', { defaultMessage: 'Maximum table cell height', }), value: 115, - description: i18n.translate('discover.advancedSettings.maxCellHeightText', { + description: i18n.translate('core.ui_settings.params.maxCellHeightText', { defaultMessage: 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', }), schema: schema.number({ min: 0 }), - category: ['discover'], }, buildNum: { readonly: true, From 5f7d2f1cb7f1e38e5a3716cdfb7b4488376fd534 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Wed, 13 Oct 2021 16:40:36 +0300 Subject: [PATCH 10/24] [Discover] apply suggestions --- .../server/ui_settings/settings/misc.test.ts | 31 ----------- src/core/server/ui_settings/settings/misc.ts | 12 ----- src/plugins/discover/server/ui_settings.ts | 12 +++++ .../common/converters/source.test.ts | 17 +----- .../common/converters/source.tsx | 53 +------------------ 5 files changed, 16 insertions(+), 109 deletions(-) delete mode 100644 src/core/server/ui_settings/settings/misc.test.ts diff --git a/src/core/server/ui_settings/settings/misc.test.ts b/src/core/server/ui_settings/settings/misc.test.ts deleted file mode 100644 index 7b6788664c997..0000000000000 --- a/src/core/server/ui_settings/settings/misc.test.ts +++ /dev/null @@ -1,31 +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 { UiSettingsParams } from '../../../types'; -import { getMiscUiSettings } from './misc'; - -describe('misc settings', () => { - const miscSettings = getMiscUiSettings(); - - const getValidationFn = (setting: UiSettingsParams) => (value: any) => - setting.schema.validate(value); - - describe('truncate:maxHeight', () => { - const validate = getValidationFn(miscSettings['truncate:maxHeight']); - - it('should only accept positive numeric values', () => { - expect(() => validate(127)).not.toThrow(); - expect(() => validate(-12)).toThrowErrorMatchingInlineSnapshot( - `"Value must be equal to or greater than [0]."` - ); - expect(() => validate('foo')).toThrowErrorMatchingInlineSnapshot( - `"expected value of type [number] but got [string]"` - ); - }); - }); -}); diff --git a/src/core/server/ui_settings/settings/misc.ts b/src/core/server/ui_settings/settings/misc.ts index cd9e43400d3c9..ad7411dfd12af 100644 --- a/src/core/server/ui_settings/settings/misc.ts +++ b/src/core/server/ui_settings/settings/misc.ts @@ -6,23 +6,11 @@ * Side Public License, v 1. */ -import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { UiSettingsParams } from '../types'; export const getMiscUiSettings = (): Record => { return { - 'truncate:maxHeight': { - name: i18n.translate('core.ui_settings.params.maxCellHeightTitle', { - defaultMessage: 'Maximum table cell height', - }), - value: 115, - description: i18n.translate('core.ui_settings.params.maxCellHeightText', { - defaultMessage: - 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', - }), - schema: schema.number({ min: 0 }), - }, buildNum: { readonly: true, schema: schema.maybe(schema.number()), diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index aa1b44da12bfc..ee500a8612252 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -26,6 +26,7 @@ import { SEARCH_FIELDS_FROM_SOURCE, MAX_DOC_FIELDS_DISPLAYED, SHOW_MULTIFIELDS, + TRUNCATE_MAX_HEIGHT, } from '../common'; export const getUiSettings: () => Record = () => ({ @@ -220,4 +221,15 @@ export const getUiSettings: () => Record = () => ({ category: ['discover'], schema: schema.boolean(), }, + [TRUNCATE_MAX_HEIGHT]: { + name: i18n.translate('core.ui_settings.params.maxCellHeightTitle', { + defaultMessage: 'Maximum table cell height', + }), + value: 115, + description: i18n.translate('core.ui_settings.params.maxCellHeightText', { + defaultMessage: + 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', + }), + schema: schema.number({ min: 0 }), + }, }); diff --git a/src/plugins/field_formats/common/converters/source.test.ts b/src/plugins/field_formats/common/converters/source.test.ts index d26849d91c233..02bb45b6bd830 100644 --- a/src/plugins/field_formats/common/converters/source.test.ts +++ b/src/plugins/field_formats/common/converters/source.test.ts @@ -19,20 +19,7 @@ describe('Source Format', () => { convertHtml = source.getConverterFor(HTML_CONTEXT_TYPE) as HtmlContextTypeConvert; }); - test('should use the text content type if a field is not passed', () => { - const hit = { - foo: 'bar', - number: 42, - hello: '

World

', - also: 'with "quotes" or \'single quotes\'', - }; - - expect(convertHtml(hit)).toBe( - '{"foo":"bar","number":42,"hello":"<h1>World</h1>","also":"with \\"quotes\\" or 'single quotes'"}' - ); - }); - - test('should render a description list if a field is passed', () => { + test('should render stringified object', () => { const hit = { foo: 'bar', number: 42, @@ -43,7 +30,7 @@ describe('Source Format', () => { expect( convertHtml(hit, { field: 'field', indexPattern: { formatHit: (h: string) => h }, hit }) ).toMatchInlineSnapshot( - `"
foo:
bar
number:
42
hello:

World

also:
with \\"quotes\\" or 'single quotes'
"` + `"{\\"foo\\":\\"bar\\",\\"number\\":42,\\"hello\\":\\"

World

\\",\\"also\\":\\"with \\\\\\"quotes\\\\\\" or 'single quotes'\\"}"` ); }); }); diff --git a/src/plugins/field_formats/common/converters/source.tsx b/src/plugins/field_formats/common/converters/source.tsx index 7d2da7831cf4f..413fe4592d602 100644 --- a/src/plugins/field_formats/common/converters/source.tsx +++ b/src/plugins/field_formats/common/converters/source.tsx @@ -7,33 +7,8 @@ */ import { KBN_FIELD_TYPES } from '@kbn/field-types'; -import React, { Fragment } from 'react'; -import ReactDOM from 'react-dom/server'; -import { escape, keys } from 'lodash'; -import { shortenDottedString } from '../utils'; import { FieldFormat } from '../field_format'; import { TextContextTypeConvert, HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; -import { FORMATS_UI_SETTINGS } from '../constants/ui_settings'; - -interface Props { - defPairs: Array<[string, string]>; -} -const TemplateComponent = ({ defPairs }: Props) => { - return ( -
- {defPairs.map((pair, idx) => ( - -
-
{' '} - - ))} -
- ); -}; /** @public */ export class SourceFormat extends FieldFormat { @@ -43,31 +18,7 @@ export class SourceFormat extends FieldFormat { textConvert: TextContextTypeConvert = (value: string) => JSON.stringify(value); - htmlConvert: HtmlContextTypeConvert = (value: string, options = {}) => { - const { field, hit, indexPattern } = options; - - if (!field) { - const converter = this.getConverterFor('text') as Function; - - return escape(converter(value)); - } - - const highlights: Record = (hit && hit.highlight) || {}; - // TODO: remove index pattern dependency - const formatted = hit ? indexPattern!.formatHit(hit) : {}; - const highlightPairs: Array<[string, string]> = []; - const sourcePairs: Array<[string, string]> = []; - const isShortDots = this.getConfig!(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE); - - keys(formatted).forEach((key) => { - const pairs = highlights[key] ? highlightPairs : sourcePairs; - const newField = isShortDots ? shortenDottedString(key) : key; - const val = formatted![key]; - pairs.push([newField as string, val]); - }, []); - - return ReactDOM.renderToStaticMarkup( - - ); + htmlConvert: HtmlContextTypeConvert = (value: string) => { + return JSON.stringify(value); }; } From 7a9f271360932b6494e516ef82be29ebdd9df047 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Wed, 13 Oct 2021 18:09:57 +0300 Subject: [PATCH 11/24] [Discover] fix i18n --- src/plugins/discover/server/ui_settings.ts | 4 ++-- x-pack/plugins/translations/translations/ja-JP.json | 4 ++-- x-pack/plugins/translations/translations/zh-CN.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index ee500a8612252..a6b218db0ee08 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -222,11 +222,11 @@ export const getUiSettings: () => Record = () => ({ schema: schema.boolean(), }, [TRUNCATE_MAX_HEIGHT]: { - name: i18n.translate('core.ui_settings.params.maxCellHeightTitle', { + name: i18n.translate('discover.advancedSettings.params.maxCellHeightTitle', { defaultMessage: 'Maximum table cell height', }), value: 115, - description: i18n.translate('core.ui_settings.params.maxCellHeightText', { + description: i18n.translate('discover.advancedSettings.params.maxCellHeightText', { defaultMessage: 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', }), diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 84d87cb020fe9..3f7a8340475a1 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1329,8 +1329,6 @@ "core.ui_settings.params.defaultRoute.defaultRouteTitle": "デフォルトのルート", "core.ui_settings.params.disableAnimationsText": "Kibana UIの不要なアニメーションをオフにします。変更を適用するにはページを更新してください。", "core.ui_settings.params.disableAnimationsTitle": "アニメーションを無効にする", - "core.ui_settings.params.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します", - "core.ui_settings.params.maxCellHeightTitle": "表のセルの高さの上限", "core.ui_settings.params.notifications.banner.markdownLinkText": "マークダウン対応", "core.ui_settings.params.notifications.bannerLifetimeText": "バナー通知が画面に表示される時間(ミリ秒単位)です。", "core.ui_settings.params.notifications.bannerLifetimeTitle": "バナー通知時間", @@ -2347,6 +2345,8 @@ "discover.advancedSettings.sortDefaultOrderTitle": "デフォルトの並べ替え方向", "discover.advancedSettings.sortOrderAsc": "昇順", "discover.advancedSettings.sortOrderDesc": "降順", + "discover.advancedSettings.params.maxCellHeightTitle": "表のセルの高さの上限", + "discover.advancedSettings.params.maxCellHeightText": "表のセルが使用する高さの上限です。この切り捨てを無効にするには0に設定します", "discover.backToTopLinkText": "最上部へ戻る。", "discover.badge.readOnly.text": "読み取り専用", "discover.badge.readOnly.tooltip": "検索を保存できません", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index fa78b2eae1432..3e88c5d001869 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1347,8 +1347,6 @@ "core.ui_settings.params.defaultRoute.defaultRouteTitle": "默认路由", "core.ui_settings.params.disableAnimationsText": "在 Kibana UI 中关闭所有不必要的动画。刷新页面可应用所做的更改。", "core.ui_settings.params.disableAnimationsTitle": "禁用动画", - "core.ui_settings.params.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断", - "core.ui_settings.params.maxCellHeightTitle": "最大表单元格高度", "core.ui_settings.params.notifications.banner.markdownLinkText": "Markdown 受支持", "core.ui_settings.params.notifications.bannerLifetimeText": "在屏幕上显示横幅通知的时间(毫秒)。", "core.ui_settings.params.notifications.bannerLifetimeTitle": "横幅通知生存时间", @@ -2371,6 +2369,8 @@ "discover.advancedSettings.sortDefaultOrderTitle": "默认排序方向", "discover.advancedSettings.sortOrderAsc": "升序", "discover.advancedSettings.sortOrderDesc": "降序", + "discover.advancedSettings.params.maxCellHeightTitle": "最大表单元格高度", + "discover.advancedSettings.params.maxCellHeightText": "表单元格应占用的最大高度。设置为 0 可禁用截断", "discover.backToTopLinkText": "返回顶部。", "discover.badge.readOnly.text": "只读", "discover.badge.readOnly.tooltip": "无法保存搜索", From a0e86e3602cece106eb994d4e5eb0bbe4ac22d52 Mon Sep 17 00:00:00 2001 From: Dmitry Tomashevich <39378793+Dmitriynj@users.noreply.github.com> Date: Thu, 14 Oct 2021 17:09:03 +0300 Subject: [PATCH 12/24] Update src/plugins/discover/server/ui_settings.ts Co-authored-by: Matthias Wilhelm --- src/plugins/discover/server/ui_settings.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/discover/server/ui_settings.ts b/src/plugins/discover/server/ui_settings.ts index a6b218db0ee08..1b6c78fcb4098 100644 --- a/src/plugins/discover/server/ui_settings.ts +++ b/src/plugins/discover/server/ui_settings.ts @@ -226,6 +226,7 @@ export const getUiSettings: () => Record = () => ({ defaultMessage: 'Maximum table cell height', }), value: 115, + category: ['discover'], description: i18n.translate('discover.advancedSettings.params.maxCellHeightText', { defaultMessage: 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', From 8c49f95096358eda0f5155efe917febfb5f5a4b5 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 14 Oct 2021 19:25:45 +0300 Subject: [PATCH 13/24] [Discover] fix embeddable and discover grid truncation styles --- .../doc_table/components/table_row.tsx | 10 ++++--- .../doc_table/doc_table_wrapper.tsx | 23 ++-------------- .../lib/formatters/row_formatter.tsx | 26 ++++++++++++++----- .../lib/formatters/source_formatter.tsx | 10 ++++--- .../application/components/table/table.tsx | 8 ++++-- .../components/table/table_cell_value.tsx | 13 +++------- .../components/table/table_columns.tsx | 9 +++++-- .../application/helpers/truncate_styles.ts | 24 +++++++++++++++++ .../common/converters/source.tsx | 6 +---- 9 files changed, 78 insertions(+), 51 deletions(-) create mode 100644 src/plugins/discover/public/application/helpers/truncate_styles.ts diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx index 2b96a1aa6f6b9..3873c0660c020 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx @@ -19,6 +19,7 @@ import { getSingleDocUrl } from '../../../../../helpers/get_single_doc_url'; import { TableRowDetails } from './table_row_details'; import { formatRow, formatTopLevelObject } from '../lib/formatters/row_formatter'; import { formatSource } from '../lib/formatters/source_formatter'; +import { getTruncateStyles } from '../../../../../helpers/truncate_styles'; export type DocTableRow = ElasticSearchHit & { isAnchor?: boolean; @@ -37,6 +38,7 @@ export interface TableRowProps { filterManager: FilterManager; addBasePath: (path: string) => string; fieldsToShow: string[]; + maxHeight: number; } export const TableRow = ({ @@ -52,6 +54,7 @@ export const TableRow = ({ onRemoveColumn, filterManager, addBasePath, + maxHeight, }: TableRowProps) => { const [open, setOpen] = useState(false); const docTableRowClassName = classNames('kbnDocTable__row', { @@ -72,6 +75,7 @@ export const TableRow = ({ hit: row, indexPattern, isShortDots, + maxHeight, }); } @@ -80,7 +84,7 @@ export const TableRow = ({ // field formatters take care of escaping // eslint-disable-next-line react/no-danger const element = ; - return
{element}
; + return
{element}
; }; const inlineFilter = useCallback( @@ -133,7 +137,7 @@ export const TableRow = ({ } if (columns.length === 0 && useNewFieldsApi) { - const formatted = formatRow(row, indexPattern, fieldsToShow); + const formatted = formatRow(row, indexPattern, fieldsToShow, maxHeight); rowCells.push( JSX.Element; } -const TRUNCATE_GRADIENT_HEIGHT = 15; - const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); export const DocTableWrapper = forwardRef( @@ -217,6 +214,7 @@ export const DocTableWrapper = forwardRef( filterManager={filterManager} addBasePath={addBasePath} fieldsToShow={fieldsToShow} + maxHeight={maxHeight} /> )); }, @@ -232,26 +230,10 @@ export const DocTableWrapper = forwardRef( addBasePath, isShortDots, fieldsToShow, + maxHeight, ] ); - const truncateStyles = ( - 0 ? `${maxHeight}px !important` : 'none'}; - display: inline-block; - } - .truncate-by-height:before { - top: ${maxHeight > 0 - ? maxHeight - TRUNCATE_GRADIENT_HEIGHT - : TRUNCATE_GRADIENT_HEIGHT * -1}px; - } - `} - /> - ); - const noResultsError = (
@@ -275,7 +257,6 @@ export const DocTableWrapper = forwardRef( data-render-complete={!isLoading} ref={ref as React.MutableRefObject} > - {maxHeight !== 0 && truncateStyles} {rows.length !== 0 && render({ columnLength: columns.length, diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx index 5edba742e93af..f1ce55f1d1081 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.tsx @@ -8,6 +8,7 @@ import React, { Fragment } from 'react'; import type { IndexPattern } from 'src/plugins/data/common'; +import { getTruncateStyles } from '../../../../../../helpers/truncate_styles'; import { MAX_DOC_FIELDS_DISPLAYED } from '../../../../../../../../common'; import { getServices } from '../../../../../../../kibana_services'; @@ -15,10 +16,11 @@ import './row_formatter.scss'; interface Props { defPairs: Array<[string, unknown]>; + maxHeight: number; } -const TemplateComponent = ({ defPairs }: Props) => { +const TemplateComponent = ({ defPairs, maxHeight }: Props) => { return ( -
+
{defPairs.map((pair, idx) => (
{pair[0]}:
@@ -37,7 +39,8 @@ export const formatRow = ( // eslint-disable-next-line @typescript-eslint/no-explicit-any hit: Record, indexPattern: IndexPattern, - fieldsToShow: string[] + fieldsToShow: string[], + maxHeight: number ) => { const highlights = hit?.highlight ?? {}; // Keys are sorted in the hits object @@ -57,7 +60,12 @@ export const formatRow = ( } }); const maxEntries = getServices().uiSettings.get(MAX_DOC_FIELDS_DISPLAYED); - return ; + return ( + + ); }; export const formatTopLevelObject = ( @@ -65,7 +73,8 @@ export const formatTopLevelObject = ( row: Record, // eslint-disable-next-line @typescript-eslint/no-explicit-any fields: Record, - indexPattern: IndexPattern + indexPattern: IndexPattern, + maxHeight: number ) => { const highlights = row.highlight ?? {}; const highlightPairs: Array<[string, unknown]> = []; @@ -91,5 +100,10 @@ export const formatTopLevelObject = ( pairs.push([displayKey ? displayKey : key, formatted]); }); const maxEntries = getServices().uiSettings.get(MAX_DOC_FIELDS_DISPLAYED); - return ; + return ( + + ); }; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx index a0c3efe5c5e4a..94ebc78650ba4 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.tsx @@ -11,14 +11,16 @@ import { escape } from 'lodash'; import { DocTableRow } from '../../components/table_row'; import { shortenDottedString } from '../../../../../../../../../field_formats/common'; import { IndexPattern } from '../../../../../../../../../data/public'; +import { getTruncateStyles } from '../../../../../../helpers/truncate_styles'; interface Props { defPairs: Array<[string, string]>; + maxHeight: number; } -const TemplateComponent = ({ defPairs }: Props) => { +const TemplateComponent = ({ maxHeight, defPairs }: Props) => { return ( -
+
{defPairs.map((pair, idx) => (
{ const highlights: Record = (hit && hit.highlight) || {}; // TODO: remove index pattern dependency @@ -55,5 +59,5 @@ export const formatSource = ({ pairs.push([newField as string, val]); }, []); - return ; + return ; }; diff --git a/src/plugins/discover/public/application/components/table/table.tsx b/src/plugins/discover/public/application/components/table/table.tsx index eab3ba6e3d29a..ed5b2b507e781 100644 --- a/src/plugins/discover/public/application/components/table/table.tsx +++ b/src/plugins/discover/public/application/components/table/table.tsx @@ -9,7 +9,7 @@ import React, { useCallback, useMemo } from 'react'; import { EuiInMemoryTable } from '@elastic/eui'; import { IndexPattern, IndexPatternField } from '../../../../../data/public'; -import { SHOW_MULTIFIELDS } from '../../../../common'; +import { SHOW_MULTIFIELDS, TRUNCATE_MAX_HEIGHT } from '../../../../common'; import { getServices } from '../../../kibana_services'; import { isNestedFieldParent } from '../../apps/main/utils/nested_fields'; import { @@ -44,6 +44,7 @@ export interface FieldRecord { fieldMapping?: IndexPatternField; }; value: { + maxHeight: number; formattedValue: string; }; } @@ -56,7 +57,9 @@ export const DocViewerTable = ({ onAddColumn, onRemoveColumn, }: DocViewRenderProps) => { - const showMultiFields = getServices().uiSettings.get(SHOW_MULTIFIELDS); + const services = getServices(); + const showMultiFields = services.uiSettings.get(SHOW_MULTIFIELDS); + const maxHeight = services.uiSettings.get(TRUNCATE_MAX_HEIGHT); const mapping = useCallback( (name: string) => indexPattern?.fields.getByName(name), @@ -129,6 +132,7 @@ export const DocViewerTable = ({ scripted: Boolean(fieldMapping?.scripted), }, value: { + maxHeight, formattedValue: formattedHit[field], }, }; 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 index 22c84b23949e1..3d95c23f91320 100644 --- a/src/plugins/discover/public/application/components/table/table_cell_value.tsx +++ b/src/plugins/discover/public/application/components/table/table_cell_value.tsx @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import classNames from 'classnames'; import React, { Fragment, useState } from 'react'; +import { getTruncateStyles } from '../../helpers/truncate_styles'; import { FieldRecord } from './table'; import { DocViewTableRowBtnCollapse } from './table_row_btn_collapse'; @@ -15,19 +15,13 @@ const COLLAPSE_LINE_LENGTH = 350; type TableFieldValueProps = FieldRecord['value'] & Pick; -export const TableFieldValue = ({ formattedValue, field }: TableFieldValueProps) => { +export const TableFieldValue = ({ maxHeight, formattedValue, field }: TableFieldValueProps) => { const [fieldOpen, setFieldOpen] = useState(false); const value = String(formattedValue); const isCollapsible = value.length > COLLAPSE_LINE_LENGTH; const isCollapsed = isCollapsible && !fieldOpen; - const valueClassName = classNames({ - // eslint-disable-next-line @typescript-eslint/naming-convention - kbnDocViewer__value: true, - 'truncate-by-height': isCollapsible && isCollapsed, - }); - const onToggleCollapse = () => setFieldOpen((fieldOpenPrev) => !fieldOpenPrev); return ( @@ -36,7 +30,8 @@ export const TableFieldValue = ({ formattedValue, field }: TableFieldValueProps) )}
> = [ ), - render: ({ formattedValue }: FieldRecord['value'], { field: { field } }: FieldRecord) => { - return ; + render: ( + { maxHeight, formattedValue }: FieldRecord['value'], + { field: { field } }: FieldRecord + ) => { + return ( + + ); }, }, ]; diff --git a/src/plugins/discover/public/application/helpers/truncate_styles.ts b/src/plugins/discover/public/application/helpers/truncate_styles.ts new file mode 100644 index 0000000000000..1478ed71bdb60 --- /dev/null +++ b/src/plugins/discover/public/application/helpers/truncate_styles.ts @@ -0,0 +1,24 @@ +/* + * 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 { css } from '@emotion/react'; + +const TRUNCATE_GRADIENT_HEIGHT = 5; + +export const getTruncateStyles = (maxHeight: number) => { + return css` + display: inline-block; + max-height: ${maxHeight > 0 ? `${maxHeight}px !important` : 'none'}; + overflow: hidden; + &:before { + top: ${maxHeight > 0 + ? maxHeight - TRUNCATE_GRADIENT_HEIGHT + : TRUNCATE_GRADIENT_HEIGHT * -1}px; + } + `; +}; diff --git a/src/plugins/field_formats/common/converters/source.tsx b/src/plugins/field_formats/common/converters/source.tsx index 413fe4592d602..f92027ec07451 100644 --- a/src/plugins/field_formats/common/converters/source.tsx +++ b/src/plugins/field_formats/common/converters/source.tsx @@ -8,7 +8,7 @@ import { KBN_FIELD_TYPES } from '@kbn/field-types'; import { FieldFormat } from '../field_format'; -import { TextContextTypeConvert, HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; +import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; /** @public */ export class SourceFormat extends FieldFormat { @@ -17,8 +17,4 @@ export class SourceFormat extends FieldFormat { static fieldType = KBN_FIELD_TYPES._SOURCE; textConvert: TextContextTypeConvert = (value: string) => JSON.stringify(value); - - htmlConvert: HtmlContextTypeConvert = (value: string) => { - return JSON.stringify(value); - }; } From 53377512bcd7bddbbb09ea22f8274898afea241f Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Fri, 15 Oct 2021 14:43:46 +0300 Subject: [PATCH 14/24] [Discover] fix tests --- .../lib/formatters/row_formatter.test.ts | 28 +++++++++++++------ .../lib/formatters/source_formatter.test.tsx | 3 +- .../components/table/table.test.tsx | 2 -- .../components/table/table_cell_value.tsx | 2 +- .../application/helpers/truncate_styles.ts | 2 ++ .../common/converters/source.test.ts | 2 +- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.test.ts b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.test.ts index c580dd9569243..f3a8a8f746327 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.test.ts +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/row_formatter.test.ts @@ -13,6 +13,7 @@ import { DiscoverServices } from '../../../../../../../build_services'; import { indexPattern, hit } from './mocks'; describe('Row formatter', () => { + const maxHeight = 115; const fieldsToShow = indexPattern.fields.getAll().map((fld) => fld.name); // Realistic response with alphabetical insertion order @@ -39,7 +40,7 @@ describe('Row formatter', () => { }); it('formats document properly', () => { - expect(formatRow(hit, indexPattern, fieldsToShow)).toMatchInlineSnapshot(` + expect(formatRow(hit, indexPattern, fieldsToShow, maxHeight)).toMatchInlineSnapshot(` { ], ] } + maxHeight={115} /> `); }); @@ -83,7 +85,7 @@ describe('Row formatter', () => { get: () => 1, }, } as unknown as DiscoverServices); - expect(formatRow(hit, indexPattern, [])).toMatchInlineSnapshot(` + expect(formatRow(hit, indexPattern, [], maxHeight)).toMatchInlineSnapshot(` { ], ] } + maxHeight={115} /> `); }); it('formats document with highlighted fields first', () => { - expect(formatRow({ ...hit, highlight: { number: '42' } }, indexPattern, fieldsToShow)) - .toMatchInlineSnapshot(` + expect( + formatRow({ ...hit, highlight: { number: '42' } }, indexPattern, fieldsToShow, maxHeight) + ).toMatchInlineSnapshot(` { ], ] } + maxHeight={115} /> `); }); @@ -155,7 +160,8 @@ describe('Row formatter', () => { 'object.value': [5, 10], getByName: jest.fn(), }, - indexPattern + indexPattern, + maxHeight ) ).toMatchInlineSnapshot(` { ], ] } + maxHeight={115} /> `); }); @@ -182,7 +189,8 @@ describe('Row formatter', () => { formatTopLevelObject( { fields: { 'a.zzz': [100], 'a.ccc': [50] } }, { 'a.zzz': [100], 'a.ccc': [50], getByName: jest.fn() }, - indexPattern + indexPattern, + maxHeight ) ); expect(formatted.indexOf('
a.ccc:
')).toBeLessThan(formatted.indexOf('
a.zzz:
')); @@ -211,7 +219,8 @@ describe('Row formatter', () => { 'object.keys': ['a', 'b'], getByName: jest.fn(), }, - indexPattern + indexPattern, + maxHeight ) ).toMatchInlineSnapshot(` { ], ] } + maxHeight={115} /> `); }); @@ -245,7 +255,8 @@ describe('Row formatter', () => { 'object.value': [5, 10], getByName: jest.fn(), }, - indexPattern + indexPattern, + maxHeight ) ).toMatchInlineSnapshot(` { ], ] } + maxHeight={115} /> `); }); diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.test.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.test.tsx index bb0ada208a3d2..67e27d4019c2f 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.test.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/formatters/source_formatter.test.tsx @@ -11,7 +11,7 @@ import { hit, indexPattern } from './mocks'; describe('_source formatter', () => { it('should format properly', () => { - const element = formatSource({ hit, indexPattern, isShortDots: true }); + const element = formatSource({ hit, indexPattern, isShortDots: true, maxHeight: 115 }); expect(element).toMatchInlineSnapshot(` { ], ] } + maxHeight={115} /> `); }); 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 3f010d9d07737..1055d7456ea24 100644 --- a/src/plugins/discover/public/application/components/table/table.test.tsx +++ b/src/plugins/discover/public/application/components/table/table.test.tsx @@ -235,8 +235,6 @@ describe('DocViewTable at Discover Context', () => { const btn = findTestSubject(component, `collapseBtn`); const html = component.html(); - expect(component.html()).toContain('truncate-by-height'); - expect(btn.length).toBe(1); btn.simulate('click'); expect(component.html() !== html).toBeTruthy(); 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 index 3d95c23f91320..fef362fb01570 100644 --- a/src/plugins/discover/public/application/components/table/table_cell_value.tsx +++ b/src/plugins/discover/public/application/components/table/table_cell_value.tsx @@ -31,7 +31,7 @@ export const TableFieldValue = ({ maxHeight, formattedValue, field }: TableField )}
{ + // emotion does not applies the first style return css` + display: inline-block; display: inline-block; max-height: ${maxHeight > 0 ? `${maxHeight}px !important` : 'none'}; overflow: hidden; diff --git a/src/plugins/field_formats/common/converters/source.test.ts b/src/plugins/field_formats/common/converters/source.test.ts index 02bb45b6bd830..c51698e510e92 100644 --- a/src/plugins/field_formats/common/converters/source.test.ts +++ b/src/plugins/field_formats/common/converters/source.test.ts @@ -30,7 +30,7 @@ describe('Source Format', () => { expect( convertHtml(hit, { field: 'field', indexPattern: { formatHit: (h: string) => h }, hit }) ).toMatchInlineSnapshot( - `"{\\"foo\\":\\"bar\\",\\"number\\":42,\\"hello\\":\\"

World

\\",\\"also\\":\\"with \\\\\\"quotes\\\\\\" or 'single quotes'\\"}"` + `"{"foo":"bar","number":42,"hello":"<h1>World</h1>","also":"with \\\\"quotes\\\\" or 'single quotes'"}"` ); }); }); From b5069b0913d4d632a8dc4d5f9b882ba37959305d Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Fri, 15 Oct 2021 14:57:40 +0300 Subject: [PATCH 15/24] [Discover] get rid of emotion --- .../application/helpers/truncate_styles.ts | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/plugins/discover/public/application/helpers/truncate_styles.ts b/src/plugins/discover/public/application/helpers/truncate_styles.ts index 04d620872a03e..617edd14e9828 100644 --- a/src/plugins/discover/public/application/helpers/truncate_styles.ts +++ b/src/plugins/discover/public/application/helpers/truncate_styles.ts @@ -6,21 +6,15 @@ * Side Public License, v 1. */ -import { css } from '@emotion/react'; - const TRUNCATE_GRADIENT_HEIGHT = 5; export const getTruncateStyles = (maxHeight: number) => { - // emotion does not applies the first style - return css` - display: inline-block; - display: inline-block; - max-height: ${maxHeight > 0 ? `${maxHeight}px !important` : 'none'}; - overflow: hidden; - &:before { - top: ${maxHeight > 0 - ? maxHeight - TRUNCATE_GRADIENT_HEIGHT - : TRUNCATE_GRADIENT_HEIGHT * -1}px; - } - `; + return { + display: 'inline-block', + maxHeight: maxHeight > 0 ? maxHeight : 'none', + overflow: 'hidden', + '&:before': { + top: maxHeight > 0 ? maxHeight - TRUNCATE_GRADIENT_HEIGHT : TRUNCATE_GRADIENT_HEIGHT * -1, + }, + }; }; From 220ffc7b2fc18193b83615ec7a1562ac5169b8d7 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Wed, 20 Oct 2021 19:15:36 +0300 Subject: [PATCH 16/24] [Discover] apply suggestions --- .../public/application/dashboard_app.tsx | 22 ++++++ .../public/application/discover_router.tsx | 78 ++++++++++++------- 2 files changed, 74 insertions(+), 26 deletions(-) diff --git a/src/plugins/dashboard/public/application/dashboard_app.tsx b/src/plugins/dashboard/public/application/dashboard_app.tsx index 3e6566f0da0a4..1de2397cc942b 100644 --- a/src/plugins/dashboard/public/application/dashboard_app.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app.tsx @@ -9,6 +9,7 @@ import { History } from 'history'; import React, { useEffect, useMemo } from 'react'; +import { css, Global } from '@emotion/react'; import { useDashboardSelector } from './state'; import { useDashboardAppState } from './hooks'; import { useKibana } from '../../../kibana_react/public'; @@ -29,6 +30,8 @@ export interface DashboardAppProps { embedSettings?: DashboardEmbedSettings; } +const TRUNCATE_GRADIENT_HEIGHT = 15; + export function DashboardApp({ savedDashboardId, embedSettings, @@ -37,6 +40,7 @@ export function DashboardApp({ }: DashboardAppProps) { const { core, chrome, embeddable, onAppLeave, uiSettings, data, spacesService } = useKibana().services; + const maxHeight = useMemo(() => uiSettings.get('truncate:maxHeight'), [uiSettings]); const kbnUrlStateStorage = useMemo( () => @@ -101,8 +105,26 @@ export function DashboardApp({ }; }, [data.search.session]); + const discoverEmbeddableTruncateStyles = ( + 0 ? `${maxHeight}px !important` : 'none'}; + display: inline-block; + } + .truncate-by-height:before { + top: ${maxHeight > 0 + ? maxHeight - TRUNCATE_GRADIENT_HEIGHT + : TRUNCATE_GRADIENT_HEIGHT * -1}px; + } + `} + /> + ); + return ( <> + {maxHeight !== 0 && discoverEmbeddableTruncateStyles} {isCompleteDashboardAppState(dashboardAppState) && ( <> { const mainRouteProps: DiscoverMainProps = { services, history, }; + const maxHeight = services.uiSettings.get(TRUNCATE_MAX_HEIGHT); + + const truncateStyles = ( + 0 ? `${maxHeight}px !important` : 'none'}; + display: inline-block; + } + .truncate-by-height:before { + top: ${maxHeight > 0 + ? maxHeight - TRUNCATE_GRADIENT_HEIGHT + : TRUNCATE_GRADIENT_HEIGHT * -1}px; + } + `} + /> + ); + return ( - - - - } - /> - ( - - )} - /> - } - /> - } /> - } /> - - - - + + {maxHeight !== 0 && truncateStyles} + + + + } + /> + ( + + )} + /> + } + /> + } /> + } /> + + + + + ); }; From 71af85d261fb6eb1ae4aec53fa10a5f71756dd73 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 21 Oct 2021 13:08:20 +0300 Subject: [PATCH 17/24] [Discover] inject emotion styles properly --- package.json | 3 ++ .../public/application/dashboard_app.tsx | 22 ----------- .../public/application/discover_router.tsx | 23 ----------- .../application/helpers/truncate_styles.ts | 39 +++++++++++++++++++ src/plugins/discover/public/plugin.tsx | 5 +++ yarn.lock | 34 +++++++++++++++- 6 files changed, 80 insertions(+), 46 deletions(-) create mode 100644 src/plugins/discover/public/application/helpers/truncate_styles.ts diff --git a/package.json b/package.json index f4706b5afe7cd..2ff27fad83cab 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,10 @@ "@elastic/request-crypto": "1.1.4", "@elastic/safer-lodash-set": "link:bazel-bin/packages/elastic-safer-lodash-set", "@elastic/search-ui-app-search-connector": "^1.6.0", + "@emotion/cache": "^11.4.0", + "@emotion/css": "^11.4.0", "@emotion/react": "^11.4.0", + "@emotion/serialize": "^1.0.2", "@hapi/accept": "^5.0.2", "@hapi/boom": "^9.1.4", "@hapi/cookie": "^11.0.2", diff --git a/src/plugins/dashboard/public/application/dashboard_app.tsx b/src/plugins/dashboard/public/application/dashboard_app.tsx index 1de2397cc942b..3e6566f0da0a4 100644 --- a/src/plugins/dashboard/public/application/dashboard_app.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app.tsx @@ -9,7 +9,6 @@ import { History } from 'history'; import React, { useEffect, useMemo } from 'react'; -import { css, Global } from '@emotion/react'; import { useDashboardSelector } from './state'; import { useDashboardAppState } from './hooks'; import { useKibana } from '../../../kibana_react/public'; @@ -30,8 +29,6 @@ export interface DashboardAppProps { embedSettings?: DashboardEmbedSettings; } -const TRUNCATE_GRADIENT_HEIGHT = 15; - export function DashboardApp({ savedDashboardId, embedSettings, @@ -40,7 +37,6 @@ export function DashboardApp({ }: DashboardAppProps) { const { core, chrome, embeddable, onAppLeave, uiSettings, data, spacesService } = useKibana().services; - const maxHeight = useMemo(() => uiSettings.get('truncate:maxHeight'), [uiSettings]); const kbnUrlStateStorage = useMemo( () => @@ -105,26 +101,8 @@ export function DashboardApp({ }; }, [data.search.session]); - const discoverEmbeddableTruncateStyles = ( - 0 ? `${maxHeight}px !important` : 'none'}; - display: inline-block; - } - .truncate-by-height:before { - top: ${maxHeight > 0 - ? maxHeight - TRUNCATE_GRADIENT_HEIGHT - : TRUNCATE_GRADIENT_HEIGHT * -1}px; - } - `} - /> - ); - return ( <> - {maxHeight !== 0 && discoverEmbeddableTruncateStyles} {isCompleteDashboardAppState(dashboardAppState) && ( <> { const mainRouteProps: DiscoverMainProps = { services, history, }; - const maxHeight = services.uiSettings.get(TRUNCATE_MAX_HEIGHT); - - const truncateStyles = ( - 0 ? `${maxHeight}px !important` : 'none'}; - display: inline-block; - } - .truncate-by-height:before { - top: ${maxHeight > 0 - ? maxHeight - TRUNCATE_GRADIENT_HEIGHT - : TRUNCATE_GRADIENT_HEIGHT * -1}px; - } - `} - /> - ); return ( - {maxHeight !== 0 && truncateStyles} diff --git a/src/plugins/discover/public/application/helpers/truncate_styles.ts b/src/plugins/discover/public/application/helpers/truncate_styles.ts new file mode 100644 index 0000000000000..27fb498dc943c --- /dev/null +++ b/src/plugins/discover/public/application/helpers/truncate_styles.ts @@ -0,0 +1,39 @@ +/* + * 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 createCache from '@emotion/cache'; +import { cache } from '@emotion/css'; +import { serializeStyles } from '@emotion/serialize'; +import { IUiSettingsClient } from 'kibana/public'; +import { TRUNCATE_MAX_HEIGHT } from '../../../common'; + +const TRUNCATE_GRADIENT_HEIGHT = 15; +const globalThemeCache = createCache({ key: 'truncation' }); + +export function injectTruncateStyles(uiSettings: IUiSettingsClient) { + const maxHeight = uiSettings.get(TRUNCATE_MAX_HEIGHT); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const truncateStyles: any = ` + .truncate-by-height { + overflow: hidden; + max-height: ${maxHeight > 0 ? `${maxHeight}px !important` : 'none'}; + display: inline-block; + } + .truncate-by-height:before { + top: ${ + maxHeight > 0 ? maxHeight - TRUNCATE_GRADIENT_HEIGHT : TRUNCATE_GRADIENT_HEIGHT * -1 + }px; + } + `; + + const serialized = serializeStyles(truncateStyles, cache.registered); + + if (!globalThemeCache.inserted[serialized.name]) { + globalThemeCache.insert('', serialized, globalThemeCache.sheet, true); + } +} diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index e170e61f7ebc5..b8df94f88ecdc 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -62,6 +62,7 @@ import { DeferredSpinner } from './shared'; import { ViewSavedSearchAction } from './application/embeddable/view_saved_search_action'; import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public'; import { FieldFormatsStart } from '../../field_formats/public'; +import { injectTruncateStyles } from './application/helpers/truncate_styles'; declare module '../../share/public' { export interface UrlGeneratorStateMapping { @@ -408,6 +409,10 @@ export class DiscoverPlugin const services = buildServices(core, plugins, this.initializerContext); setServices(services); + // eslint-disable-next-line no-console + console.log('starting'); + injectTruncateStyles(services.uiSettings); + return { urlGenerator: this.urlGenerator, locator: this.locator, diff --git a/yarn.lock b/yarn.lock index 375e748564283..64fed9bc7c562 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2580,7 +2580,7 @@ dependencies: "@babel/plugin-syntax-jsx" "^7.2.0" -"@emotion/babel-plugin@^11.2.0": +"@emotion/babel-plugin@^11.0.0", "@emotion/babel-plugin@^11.2.0": version "11.2.0" resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.2.0.tgz#f25c6df8ec045dad5ae6ca63df0791673b98c920" integrity sha512-lsnQBnl3l4wu/FJoyHnYRpHJeIPNkOBMbtDUIXcO8luulwRKZXPvA10zd2eXVN6dABIWNX4E34en/jkejIg/yA== @@ -2641,6 +2641,17 @@ "@emotion/weak-memoize" "^0.2.5" stylis "^4.0.3" +"@emotion/cache@^11.5.0": + version "11.5.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.5.0.tgz#a5eb78cbef8163939ee345e3ddf0af217b845e62" + integrity sha512-mAZ5QRpLriBtaj/k2qyrXwck6yeoz1V5lMt/jfj6igWU35yYlNKs2LziXVgvH81gnJZ+9QQNGelSsnuoAy6uIw== + dependencies: + "@emotion/memoize" "^0.7.4" + "@emotion/sheet" "^1.0.3" + "@emotion/utils" "^1.0.0" + "@emotion/weak-memoize" "^0.2.5" + stylis "^4.0.10" + "@emotion/core@^10.0.9", "@emotion/core@^10.1.1": version "10.1.1" resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3" @@ -2670,6 +2681,17 @@ "@emotion/utils" "0.11.3" babel-plugin-emotion "^10.0.27" +"@emotion/css@^11.4.0": + version "11.5.0" + resolved "https://registry.yarnpkg.com/@emotion/css/-/css-11.5.0.tgz#0a80017080cb44d47994fe576b9923bfc8b0f6ad" + integrity sha512-mqjz/3aqR9rp40M+pvwdKYWxlQK4Nj3cnNjo3Tx6SM14dSsEn7q/4W2/I7PlgG+mb27iITHugXuBIHH/QwUBVQ== + dependencies: + "@emotion/babel-plugin" "^11.0.0" + "@emotion/cache" "^11.5.0" + "@emotion/serialize" "^1.0.0" + "@emotion/sheet" "^1.0.3" + "@emotion/utils" "^1.0.0" + "@emotion/hash@0.8.0", "@emotion/hash@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" @@ -2768,6 +2790,11 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.1.tgz#245f54abb02dfd82326e28689f34c27aa9b2a698" integrity sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g== +"@emotion/sheet@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.3.tgz#00c326cd7985c5ccb8fe2c1b592886579dcfab8f" + integrity sha512-YoX5GyQ4db7LpbmXHMuc8kebtBGP6nZfRC5Z13OKJMixBEwdZrJ914D6yJv/P+ZH/YY3F5s89NYX2hlZAf3SRQ== + "@emotion/styled-base@^10.0.27": version "10.0.31" resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.0.31.tgz#940957ee0aa15c6974adc7d494ff19765a2f742a" @@ -27198,6 +27225,11 @@ stylis@^3.5.0: resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== +stylis@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240" + integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg== + stylis@^4.0.3: version "4.0.7" resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.7.tgz#412a90c28079417f3d27c028035095e4232d2904" From 0d9493d90ccca4a88d51ec265fd5ff9f50be28a6 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 21 Oct 2021 13:09:35 +0300 Subject: [PATCH 18/24] [Discover] remove console.log --- src/plugins/discover/public/plugin.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index b8df94f88ecdc..46904a2e202f5 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -409,8 +409,6 @@ export class DiscoverPlugin const services = buildServices(core, plugins, this.initializerContext); setServices(services); - // eslint-disable-next-line no-console - console.log('starting'); injectTruncateStyles(services.uiSettings); return { From d3d4372c2eb2a0a1a3612f9eff3b5a50c90ce0d6 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 21 Oct 2021 15:27:58 +0300 Subject: [PATCH 19/24] [Discover] revert react router changes --- .../public/application/discover_router.tsx | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/plugins/discover/public/application/discover_router.tsx b/src/plugins/discover/public/application/discover_router.tsx index b157237ab4e3f..b3fe36358bbd4 100644 --- a/src/plugins/discover/public/application/discover_router.tsx +++ b/src/plugins/discover/public/application/discover_router.tsx @@ -7,7 +7,7 @@ */ import { Redirect, Route, Router, Switch } from 'react-router-dom'; -import React, { Fragment } from 'react'; +import React from 'react'; import { History } from 'history'; import { KibanaContextProvider } from '../../../kibana_react/public'; import { ContextAppRoute } from './apps/context'; @@ -24,32 +24,30 @@ export const discoverRouter = (services: DiscoverServices, history: History) => }; return ( - - - - - } - /> - ( - - )} - /> - } - /> - } /> - } /> - - - - - + + + + } + /> + ( + + )} + /> + } + /> + } /> + } /> + + + + ); }; From 7f6b8788d9e8f5b635918176f5a388cf0bf6b3c4 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 21 Oct 2021 15:58:26 +0300 Subject: [PATCH 20/24] [Discover] fix truncate max height reset --- .../application/helpers/truncate_styles.ts | 24 ++++++++++++++----- src/plugins/discover/public/plugin.tsx | 4 ++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/plugins/discover/public/application/helpers/truncate_styles.ts b/src/plugins/discover/public/application/helpers/truncate_styles.ts index 27fb498dc943c..57693e8a015f0 100644 --- a/src/plugins/discover/public/application/helpers/truncate_styles.ts +++ b/src/plugins/discover/public/application/helpers/truncate_styles.ts @@ -15,10 +15,8 @@ import { TRUNCATE_MAX_HEIGHT } from '../../../common'; const TRUNCATE_GRADIENT_HEIGHT = 15; const globalThemeCache = createCache({ key: 'truncation' }); -export function injectTruncateStyles(uiSettings: IUiSettingsClient) { - const maxHeight = uiSettings.get(TRUNCATE_MAX_HEIGHT); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const truncateStyles: any = ` +const buildStylesheet = (maxHeight: number) => { + return ` .truncate-by-height { overflow: hidden; max-height: ${maxHeight > 0 ? `${maxHeight}px !important` : 'none'}; @@ -30,10 +28,24 @@ export function injectTruncateStyles(uiSettings: IUiSettingsClient) { }px; } `; +}; + +const flushThemedGlobals = () => { + globalThemeCache.sheet.flush(); + globalThemeCache.inserted = {}; + globalThemeCache.registered = {}; +}; - const serialized = serializeStyles(truncateStyles, cache.registered); +export const injectTruncateStyles = (uiSettings: IUiSettingsClient) => { + const maxHeight = uiSettings.get(TRUNCATE_MAX_HEIGHT); + if (maxHeight === 0) { + flushThemedGlobals(); + return; + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const serialized = serializeStyles(buildStylesheet(maxHeight) as any, cache.registered); if (!globalThemeCache.inserted[serialized.name]) { globalThemeCache.insert('', serialized, globalThemeCache.sheet, true); } -} +}; diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 46904a2e202f5..3b15c11d5ac68 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -44,6 +44,7 @@ import { setScopedHistory, getScopedHistory, syncHistoryLocations, + getServices, } from './kibana_services'; import { registerFeature } from './register_feature'; import { buildServices } from './build_services'; @@ -340,6 +341,7 @@ export class DiscoverPlugin setHeaderActionMenuMounter(params.setHeaderActionMenu); syncHistoryLocations(); appMounted(); + injectTruncateStyles(getServices().uiSettings); // dispatch synthetic hash change event to update hash history objects // this is necessary because hash updates triggered by using popState won't trigger this event naturally. const unlistenParentHistory = params.history.listen(() => { @@ -409,8 +411,6 @@ export class DiscoverPlugin const services = buildServices(core, plugins, this.initializerContext); setServices(services); - injectTruncateStyles(services.uiSettings); - return { urlGenerator: this.urlGenerator, locator: this.locator, From ca1a41f1ebbbf90020bdfb6931716df5c09777a0 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 21 Oct 2021 16:01:33 +0300 Subject: [PATCH 21/24] [Discover] simplify --- .../discover/public/application/helpers/truncate_styles.ts | 5 +---- src/plugins/discover/public/plugin.tsx | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/plugins/discover/public/application/helpers/truncate_styles.ts b/src/plugins/discover/public/application/helpers/truncate_styles.ts index 57693e8a015f0..8dd0d2c54af4c 100644 --- a/src/plugins/discover/public/application/helpers/truncate_styles.ts +++ b/src/plugins/discover/public/application/helpers/truncate_styles.ts @@ -9,8 +9,6 @@ import createCache from '@emotion/cache'; import { cache } from '@emotion/css'; import { serializeStyles } from '@emotion/serialize'; -import { IUiSettingsClient } from 'kibana/public'; -import { TRUNCATE_MAX_HEIGHT } from '../../../common'; const TRUNCATE_GRADIENT_HEIGHT = 15; const globalThemeCache = createCache({ key: 'truncation' }); @@ -36,8 +34,7 @@ const flushThemedGlobals = () => { globalThemeCache.registered = {}; }; -export const injectTruncateStyles = (uiSettings: IUiSettingsClient) => { - const maxHeight = uiSettings.get(TRUNCATE_MAX_HEIGHT); +export const injectTruncateStyles = (maxHeight: number) => { if (maxHeight === 0) { flushThemedGlobals(); return; diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 3b15c11d5ac68..1d2665e5473d7 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -64,6 +64,7 @@ import { ViewSavedSearchAction } from './application/embeddable/view_saved_searc import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public'; import { FieldFormatsStart } from '../../field_formats/public'; import { injectTruncateStyles } from './application/helpers/truncate_styles'; +import { TRUNCATE_MAX_HEIGHT } from '../common'; declare module '../../share/public' { export interface UrlGeneratorStateMapping { @@ -341,7 +342,7 @@ export class DiscoverPlugin setHeaderActionMenuMounter(params.setHeaderActionMenu); syncHistoryLocations(); appMounted(); - injectTruncateStyles(getServices().uiSettings); + injectTruncateStyles(getServices().uiSettings.get(TRUNCATE_MAX_HEIGHT)); // dispatch synthetic hash change event to update hash history objects // this is necessary because hash updates triggered by using popState won't trigger this event naturally. const unlistenParentHistory = params.history.listen(() => { From e2b69838eac62eb77bc5f9aa1d51c4ba00aa17ca Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 21 Oct 2021 16:11:17 +0300 Subject: [PATCH 22/24] [Discover] return injection to the right place --- src/plugins/discover/public/plugin.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 1d2665e5473d7..e9c6a1a0bd2ba 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -342,7 +342,6 @@ export class DiscoverPlugin setHeaderActionMenuMounter(params.setHeaderActionMenu); syncHistoryLocations(); appMounted(); - injectTruncateStyles(getServices().uiSettings.get(TRUNCATE_MAX_HEIGHT)); // dispatch synthetic hash change event to update hash history objects // this is necessary because hash updates triggered by using popState won't trigger this event naturally. const unlistenParentHistory = params.history.listen(() => { @@ -412,6 +411,8 @@ export class DiscoverPlugin const services = buildServices(core, plugins, this.initializerContext); setServices(services); + injectTruncateStyles(services.uiSettings.get(TRUNCATE_MAX_HEIGHT)); + return { urlGenerator: this.urlGenerator, locator: this.locator, From 7b87342fa96053fb1f3ef168da87aa23d25c4649 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Thu, 21 Oct 2021 16:37:27 +0300 Subject: [PATCH 23/24] [Discover] remove unused import --- src/plugins/discover/public/plugin.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index e9c6a1a0bd2ba..e7854a910dd8e 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -44,7 +44,6 @@ import { setScopedHistory, getScopedHistory, syncHistoryLocations, - getServices, } from './kibana_services'; import { registerFeature } from './register_feature'; import { buildServices } from './build_services'; From 1c5547db966fc0db07bc078c740fc20160958513 Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Sun, 31 Oct 2021 16:53:33 +0300 Subject: [PATCH 24/24] [Discover] apply suggestions --- .../doc_table/components/table_row.tsx | 2 +- .../doc_table/lib/row_formatter.tsx | 2 +- .../components/table/table.test.tsx | 2 +- .../components/table/table_cell_value.tsx | 2 +- .../application/helpers/truncate_styles.ts | 25 +++++++++++-------- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx index 0bf4a36555d16..515782ce23f45 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_row.tsx @@ -88,7 +88,7 @@ export const TableRow = ({ return ( // formatFieldValue always returns sanitized HTML // eslint-disable-next-line react/no-danger -
+
); }; const inlineFilter = useCallback( diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx index 2702a232f21ef..9d2acf0b22610 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx @@ -20,7 +20,7 @@ interface Props { } const TemplateComponent = ({ defPairs }: Props) => { return ( -
+
{defPairs.map((pair, idx) => (
{pair[0]}:
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 e61333cce1166..176a1961378aa 100644 --- a/src/plugins/discover/public/application/components/table/table.test.tsx +++ b/src/plugins/discover/public/application/components/table/table.test.tsx @@ -236,7 +236,7 @@ describe('DocViewTable at Discover Context', () => { const btn = findTestSubject(component, `collapseBtn`); const html = component.html(); - expect(component.html()).toContain('truncate-by-height'); + expect(component.html()).toContain('dscTruncateByHeight'); expect(btn.length).toBe(1); btn.simulate('click'); 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 index e006de1cd7aeb..ebb4ea243fb25 100644 --- a/src/plugins/discover/public/application/components/table/table_cell_value.tsx +++ b/src/plugins/discover/public/application/components/table/table_cell_value.tsx @@ -104,7 +104,7 @@ export const TableFieldValue = ({ const valueClassName = classNames({ // eslint-disable-next-line @typescript-eslint/naming-convention kbnDocViewer__value: true, - 'truncate-by-height': isCollapsible && isCollapsed, + dscTruncateByHeight: isCollapsible && isCollapsed, }); const onToggleCollapse = () => setFieldOpen((fieldOpenPrev) => !fieldOpenPrev); diff --git a/src/plugins/discover/public/application/helpers/truncate_styles.ts b/src/plugins/discover/public/application/helpers/truncate_styles.ts index 8dd0d2c54af4c..dbe8b770e1793 100644 --- a/src/plugins/discover/public/application/helpers/truncate_styles.ts +++ b/src/plugins/discover/public/application/helpers/truncate_styles.ts @@ -10,22 +10,26 @@ import createCache from '@emotion/cache'; import { cache } from '@emotion/css'; import { serializeStyles } from '@emotion/serialize'; +/** + * The following emotion cache management was introduced here + * https://ntsim.uk/posts/how-to-update-or-remove-global-styles-in-emotion/ + */ const TRUNCATE_GRADIENT_HEIGHT = 15; const globalThemeCache = createCache({ key: 'truncation' }); const buildStylesheet = (maxHeight: number) => { - return ` - .truncate-by-height { + return [ + ` + .dscTruncateByHeight { overflow: hidden; - max-height: ${maxHeight > 0 ? `${maxHeight}px !important` : 'none'}; + max-height: ${maxHeight}px !important; display: inline-block; } - .truncate-by-height:before { - top: ${ - maxHeight > 0 ? maxHeight - TRUNCATE_GRADIENT_HEIGHT : TRUNCATE_GRADIENT_HEIGHT * -1 - }px; + .dscTruncateByHeight:before { + top: ${maxHeight - TRUNCATE_GRADIENT_HEIGHT}px; } - `; + `, + ]; }; const flushThemedGlobals = () => { @@ -35,13 +39,12 @@ const flushThemedGlobals = () => { }; export const injectTruncateStyles = (maxHeight: number) => { - if (maxHeight === 0) { + if (maxHeight <= 0) { flushThemedGlobals(); return; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const serialized = serializeStyles(buildStylesheet(maxHeight) as any, cache.registered); + const serialized = serializeStyles(buildStylesheet(maxHeight), cache.registered); if (!globalThemeCache.inserted[serialized.name]) { globalThemeCache.insert('', serialized, globalThemeCache.sheet, true); }