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( + + ); + }; +}