[FieldFormatters] Remove aggs format decorator from fieldFormats.deserialize()
(#106755)
This commit is contained in:
parent
a1513eb98a
commit
6559bf4071
31 changed files with 219 additions and 240 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import helpers from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import helpers from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
Filter helpers namespace:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import helpers from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import helpers from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import helpers from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import helpers from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [FieldFormat](./kibana-plugin-plugins-data-public.fieldformat.md) > [hidden](./kibana-plugin-plugins-data-public.fieldformat.hidden.md)
|
||||
|
||||
## FieldFormat.hidden property
|
||||
|
||||
Hidden field formats can only be accessed directly by id, They won't appear in field format editor UI, But they can be accessed and used from code internally.
|
||||
|
||||
{<!-- -->boolean<!-- -->} - Is this a hidden field format
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
static hidden: boolean;
|
||||
```
|
|
@ -25,6 +25,7 @@ export declare abstract class FieldFormat
|
|||
| [convertObject](./kibana-plugin-plugins-data-public.fieldformat.convertobject.md) | | <code>FieldFormatConvert | undefined</code> | {<!-- -->FieldFormatConvert<!-- -->} have to remove the private because of https://github.com/Microsoft/TypeScript/issues/17293 |
|
||||
| [fieldType](./kibana-plugin-plugins-data-public.fieldformat.fieldtype.md) | <code>static</code> | <code>string | string[]</code> | {<!-- -->string<!-- -->} - Field Format Type |
|
||||
| [getConfig](./kibana-plugin-plugins-data-public.fieldformat.getconfig.md) | | <code>FieldFormatsGetConfigFn | undefined</code> | |
|
||||
| [hidden](./kibana-plugin-plugins-data-public.fieldformat.hidden.md) | <code>static</code> | <code>boolean</code> | Hidden field formats can only be accessed directly by id, They won't appear in field format editor UI, But they can be accessed and used from code internally. {<!-- -->boolean<!-- -->} - Is this a hidden field format |
|
||||
| [htmlConvert](./kibana-plugin-plugins-data-public.fieldformat.htmlconvert.md) | | <code>HtmlContextTypeConvert | undefined</code> | {<!-- -->htmlConvert<!-- -->} have to remove the protected because of https://github.com/Microsoft/TypeScript/issues/17293 |
|
||||
| [id](./kibana-plugin-plugins-data-public.fieldformat.id.md) | <code>static</code> | <code>string</code> | {<!-- -->string<!-- -->} - Field Format Id |
|
||||
| [textConvert](./kibana-plugin-plugins-data-public.fieldformat.textconvert.md) | | <code>TextContextTypeConvert | undefined</code> | {<!-- -->textConvert<!-- -->} have to remove the protected because of https://github.com/Microsoft/TypeScript/issues/17293 |
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
> Warning: This API is now obsolete.
|
||||
>
|
||||
> Please import from the package kbn/es-query directly. This import will be deprecated in v8.0.0.
|
||||
> Please import from the package kbn/es-query directly. This import will be removed in v8.0.0.
|
||||
>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
|
|
@ -30,6 +30,18 @@ export abstract class FieldFormat {
|
|||
* @public
|
||||
*/
|
||||
static id: string;
|
||||
|
||||
/**
|
||||
* Hidden field formats can only be accessed directly by id,
|
||||
* They won't appear in field format editor UI,
|
||||
* But they can be accessed and used from code internally.
|
||||
*
|
||||
* @property {boolean} - Is this a hidden field format
|
||||
* @static
|
||||
* @public
|
||||
*/
|
||||
static hidden: boolean;
|
||||
|
||||
/**
|
||||
* @property {string} - Field Format Title
|
||||
* @static
|
||||
|
|
|
@ -30,7 +30,7 @@ export class FieldFormatsRegistry {
|
|||
protected defaultMap: Record<string, FieldFormatConfig> = {};
|
||||
protected metaParamsOptions: Record<string, any> = {};
|
||||
protected getConfig?: FieldFormatsGetConfigFn;
|
||||
// overriden on the public contract
|
||||
|
||||
public deserialize: FormatFactory = (mapping?: SerializedFieldFormat) => {
|
||||
if (!mapping) {
|
||||
return new (FieldFormat.from(identity))();
|
||||
|
@ -215,7 +215,8 @@ export class FieldFormatsRegistry {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get filtered list of field formats by format type
|
||||
* Get filtered list of field formats by format type,
|
||||
* Skips hidden field formats
|
||||
*
|
||||
* @param {KBN_FIELD_TYPES} fieldType
|
||||
* @return {FieldFormatInstanceType[]}
|
||||
|
@ -223,7 +224,8 @@ export class FieldFormatsRegistry {
|
|||
getByFieldType(fieldType: KBN_FIELD_TYPES): FieldFormatInstanceType[] {
|
||||
return [...this.fieldFormats.values()]
|
||||
.filter(
|
||||
(format: FieldFormatInstanceType) => format && format.fieldType.indexOf(fieldType) !== -1
|
||||
(format: FieldFormatInstanceType) =>
|
||||
format && !format.hidden && format.fieldType.indexOf(fieldType) !== -1
|
||||
)
|
||||
.map(
|
||||
(format: FieldFormatInstanceType) =>
|
||||
|
|
|
@ -82,6 +82,7 @@ export type FieldFormatInstanceType = (new (
|
|||
// Static properties:
|
||||
id: FieldFormatId;
|
||||
title: string;
|
||||
hidden?: boolean;
|
||||
fieldType: string | string[];
|
||||
};
|
||||
|
||||
|
|
|
@ -10,10 +10,20 @@ import { identity } from 'lodash';
|
|||
|
||||
import { SerializedFieldFormat } from 'src/plugins/expressions/common/types';
|
||||
import { FieldFormat, IFieldFormat } from '../../../../common';
|
||||
import { getAggsFormats } from './get_aggs_formats';
|
||||
|
||||
import { getFormatWithAggs } from './get_format_with_aggs';
|
||||
const getAggFormat = (
|
||||
mapping: SerializedFieldFormat,
|
||||
getFormat: (mapping: SerializedFieldFormat) => IFieldFormat
|
||||
) => {
|
||||
const aggsFormats = getAggsFormats(getFormat);
|
||||
const AggFormat = aggsFormats.find((format) => format.id === mapping.id);
|
||||
if (!AggFormat) throw new Error(`No agg format with id: ${mapping.id}`);
|
||||
|
||||
describe('getFormatWithAggs', () => {
|
||||
return new AggFormat(mapping.params);
|
||||
};
|
||||
|
||||
describe('getAggsFormats', () => {
|
||||
let getFormat: jest.MockedFunction<(mapping: SerializedFieldFormat) => IFieldFormat>;
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -23,19 +33,9 @@ describe('getFormatWithAggs', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('calls provided getFormat if no matching aggs exist', () => {
|
||||
const mapping = { id: 'foo', params: {} };
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
getFieldFormat(mapping);
|
||||
|
||||
expect(getFormat).toHaveBeenCalledTimes(1);
|
||||
expect(getFormat).toHaveBeenCalledWith(mapping);
|
||||
});
|
||||
|
||||
test('creates custom format for date_range', () => {
|
||||
const mapping = { id: 'date_range', params: {} };
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
const format = getFieldFormat(mapping);
|
||||
const format = getAggFormat(mapping, getFormat);
|
||||
|
||||
expect(format.convert({ from: '2020-05-01', to: '2020-06-01' })).toBe(
|
||||
'2020-05-01 to 2020-06-01'
|
||||
|
@ -47,8 +47,7 @@ describe('getFormatWithAggs', () => {
|
|||
|
||||
test('creates custom format for ip_range', () => {
|
||||
const mapping = { id: 'ip_range', params: {} };
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
const format = getFieldFormat(mapping);
|
||||
const format = getAggFormat(mapping, getFormat);
|
||||
|
||||
expect(format.convert({ type: 'range', from: '10.0.0.1', to: '10.0.0.10' })).toBe(
|
||||
'10.0.0.1 to 10.0.0.10'
|
||||
|
@ -61,8 +60,7 @@ describe('getFormatWithAggs', () => {
|
|||
|
||||
test('creates custom format for range', () => {
|
||||
const mapping = { id: 'range', params: {} };
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
const format = getFieldFormat(mapping);
|
||||
const format = getAggFormat(mapping, getFormat);
|
||||
|
||||
expect(format.convert({ gte: 1, lt: 20 })).toBe('≥ 1 and < 20');
|
||||
expect(getFormat).toHaveBeenCalledTimes(1);
|
||||
|
@ -70,8 +68,7 @@ describe('getFormatWithAggs', () => {
|
|||
|
||||
test('creates alternative format for range using the template parameter', () => {
|
||||
const mapping = { id: 'range', params: { template: 'arrow_right' } };
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
const format = getFieldFormat(mapping);
|
||||
const format = getAggFormat(mapping, getFormat);
|
||||
|
||||
expect(format.convert({ gte: 1, lt: 20 })).toBe('1 → 20');
|
||||
expect(getFormat).toHaveBeenCalledTimes(1);
|
||||
|
@ -79,8 +76,7 @@ describe('getFormatWithAggs', () => {
|
|||
|
||||
test('handles Infinity values internally when no nestedFormatter is passed', () => {
|
||||
const mapping = { id: 'range', params: { replaceInfinity: true } };
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
const format = getFieldFormat(mapping);
|
||||
const format = getAggFormat(mapping, getFormat);
|
||||
|
||||
expect(format.convert({ gte: -Infinity, lt: Infinity })).toBe('≥ −∞ and < +∞');
|
||||
expect(getFormat).toHaveBeenCalledTimes(1);
|
||||
|
@ -88,8 +84,7 @@ describe('getFormatWithAggs', () => {
|
|||
|
||||
test('lets Infinity values handling to nestedFormatter even when flag is on', () => {
|
||||
const mapping = { id: 'range', params: { replaceInfinity: true, id: 'any' } };
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
const format = getFieldFormat(mapping);
|
||||
const format = getAggFormat(mapping, getFormat);
|
||||
|
||||
expect(format.convert({ gte: -Infinity, lt: Infinity })).toBe('≥ -Infinity and < Infinity');
|
||||
expect(getFormat).toHaveBeenCalledTimes(1);
|
||||
|
@ -97,8 +92,8 @@ describe('getFormatWithAggs', () => {
|
|||
|
||||
test('returns custom label for range if provided', () => {
|
||||
const mapping = { id: 'range', params: {} };
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
const format = getFieldFormat(mapping);
|
||||
|
||||
const format = getAggFormat(mapping, getFormat);
|
||||
|
||||
expect(format.convert({ gte: 1, lt: 20, label: 'custom' })).toBe('custom');
|
||||
// underlying formatter is not called because custom label can be used directly
|
||||
|
@ -113,8 +108,8 @@ describe('getFormatWithAggs', () => {
|
|||
missingBucketLabel: 'missing bucket',
|
||||
},
|
||||
};
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
const format = getFieldFormat(mapping);
|
||||
|
||||
const format = getAggFormat(mapping, getFormat);
|
||||
|
||||
expect(format.convert('machine.os.keyword')).toBe('machine.os.keyword');
|
||||
expect(format.convert('__other__')).toBe(mapping.params.otherBucketLabel);
|
131
src/plugins/data/common/search/aggs/utils/get_aggs_formats.ts
Normal file
131
src/plugins/data/common/search/aggs/utils/get_aggs_formats.ts
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { SerializedFieldFormat } from 'src/plugins/expressions/common/types';
|
||||
import {
|
||||
FieldFormat,
|
||||
FieldFormatInstanceType,
|
||||
FieldFormatsContentType,
|
||||
IFieldFormat,
|
||||
} from '../../../../common/field_formats';
|
||||
import { convertDateRangeToString, DateRangeKey } from '../buckets/lib/date_range';
|
||||
import { convertIPRangeToString, IpRangeKey } from '../buckets/lib/ip_range';
|
||||
|
||||
type GetFieldFormat = (mapping: SerializedFieldFormat) => IFieldFormat;
|
||||
|
||||
/**
|
||||
* Certain aggs have custom field formats that have dependency on aggs code.
|
||||
* This function creates such field formats types and then those are added to field formatters registry
|
||||
*
|
||||
* These formats can't be used from field format editor UI
|
||||
*
|
||||
* This function is internal to the data plugin, and only exists for use inside
|
||||
* the field formats service.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function getAggsFormats(getFieldFormat: GetFieldFormat): FieldFormatInstanceType[] {
|
||||
return [
|
||||
class AggsRangeFieldFormat extends FieldFormat {
|
||||
static id = 'range';
|
||||
static hidden = true;
|
||||
|
||||
textConvert = (range: any) => {
|
||||
const params = this._params;
|
||||
|
||||
if (range.label) {
|
||||
return range.label;
|
||||
}
|
||||
const nestedFormatter = params as SerializedFieldFormat;
|
||||
const format = getFieldFormat({
|
||||
id: nestedFormatter.id,
|
||||
params: nestedFormatter.params,
|
||||
});
|
||||
|
||||
const gte = '\u2265';
|
||||
const lt = '\u003c';
|
||||
let fromValue = format.convert(range.gte);
|
||||
let toValue = format.convert(range.lt);
|
||||
// In case of identity formatter and a specific flag, replace Infinity values by specific strings
|
||||
if (params.replaceInfinity && nestedFormatter.id == null) {
|
||||
const FROM_PLACEHOLDER = '\u2212\u221E';
|
||||
const TO_PLACEHOLDER = '+\u221E';
|
||||
fromValue = isFinite(range.gte) ? fromValue : FROM_PLACEHOLDER;
|
||||
toValue = isFinite(range.lt) ? toValue : TO_PLACEHOLDER;
|
||||
}
|
||||
|
||||
if (params.template === 'arrow_right') {
|
||||
return i18n.translate('data.aggTypes.buckets.ranges.rangesFormatMessageArrowRight', {
|
||||
defaultMessage: '{from} → {to}',
|
||||
values: {
|
||||
from: fromValue,
|
||||
to: toValue,
|
||||
},
|
||||
});
|
||||
}
|
||||
return i18n.translate('data.aggTypes.buckets.ranges.rangesFormatMessage', {
|
||||
defaultMessage: '{gte} {from} and {lt} {to}',
|
||||
values: {
|
||||
gte,
|
||||
from: fromValue,
|
||||
lt,
|
||||
to: toValue,
|
||||
},
|
||||
});
|
||||
};
|
||||
},
|
||||
class AggsDateRangeFieldFormat extends FieldFormat {
|
||||
static id = 'date_range';
|
||||
static hidden = true;
|
||||
|
||||
textConvert = (range: DateRangeKey) => {
|
||||
const nestedFormatter = this._params as SerializedFieldFormat;
|
||||
const format = getFieldFormat({
|
||||
id: nestedFormatter.id,
|
||||
params: nestedFormatter.params,
|
||||
});
|
||||
return convertDateRangeToString(range, format.convert.bind(format));
|
||||
};
|
||||
},
|
||||
class AggsIpRangeFieldFormat extends FieldFormat {
|
||||
static id = 'ip_range';
|
||||
static hidden = true;
|
||||
|
||||
textConvert = (range: IpRangeKey) => {
|
||||
const nestedFormatter = this._params as SerializedFieldFormat;
|
||||
const format = getFieldFormat({
|
||||
id: nestedFormatter.id,
|
||||
params: nestedFormatter.params,
|
||||
});
|
||||
return convertIPRangeToString(range, format.convert.bind(format));
|
||||
};
|
||||
},
|
||||
class AggsTermsFieldFormat extends FieldFormat {
|
||||
static id = 'terms';
|
||||
static hidden = true;
|
||||
|
||||
convert = (val: string, type: FieldFormatsContentType) => {
|
||||
const params = this._params;
|
||||
const format = getFieldFormat({ id: params.id, params });
|
||||
|
||||
if (val === '__other__') {
|
||||
return params.otherBucketLabel;
|
||||
}
|
||||
if (val === '__missing__') {
|
||||
return params.missingBucketLabel;
|
||||
}
|
||||
|
||||
return format.convert(val, type);
|
||||
};
|
||||
getConverterFor = (type: FieldFormatsContentType) => (val: string) => this.convert(val, type);
|
||||
},
|
||||
];
|
||||
}
|
|
@ -1,131 +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 { SerializedFieldFormat } from 'src/plugins/expressions/common/types';
|
||||
import {
|
||||
FieldFormat,
|
||||
FieldFormatsContentType,
|
||||
IFieldFormat,
|
||||
} from '../../../../common/field_formats';
|
||||
import { convertDateRangeToString, DateRangeKey } from '../buckets/lib/date_range';
|
||||
import { convertIPRangeToString, IpRangeKey } from '../buckets/lib/ip_range';
|
||||
|
||||
type GetFieldFormat = (mapping: SerializedFieldFormat) => IFieldFormat;
|
||||
|
||||
/**
|
||||
* Certain aggs have custom field formats that are not part of the field formats
|
||||
* registry. This function will take the `getFormat` function which is used inside
|
||||
* `deserializeFieldFormat` and decorate it with the additional custom formats
|
||||
* that the field formats service doesn't know anything about.
|
||||
*
|
||||
* This function is internal to the data plugin, and only exists for use inside
|
||||
* the field formats service.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function getFormatWithAggs(getFieldFormat: GetFieldFormat): GetFieldFormat {
|
||||
return (mapping) => {
|
||||
const { id, params = {} } = mapping;
|
||||
|
||||
const customFormats: Record<string, () => IFieldFormat> = {
|
||||
range: () => {
|
||||
const RangeFormat = FieldFormat.from((range: any) => {
|
||||
if (range.label) {
|
||||
return range.label;
|
||||
}
|
||||
const nestedFormatter = params as SerializedFieldFormat;
|
||||
const format = getFieldFormat({
|
||||
id: nestedFormatter.id,
|
||||
params: nestedFormatter.params,
|
||||
});
|
||||
|
||||
const gte = '\u2265';
|
||||
const lt = '\u003c';
|
||||
let fromValue = format.convert(range.gte);
|
||||
let toValue = format.convert(range.lt);
|
||||
// In case of identity formatter and a specific flag, replace Infinity values by specific strings
|
||||
if (params.replaceInfinity && nestedFormatter.id == null) {
|
||||
const FROM_PLACEHOLDER = '\u2212\u221E';
|
||||
const TO_PLACEHOLDER = '+\u221E';
|
||||
fromValue = isFinite(range.gte) ? fromValue : FROM_PLACEHOLDER;
|
||||
toValue = isFinite(range.lt) ? toValue : TO_PLACEHOLDER;
|
||||
}
|
||||
|
||||
if (params.template === 'arrow_right') {
|
||||
return i18n.translate('data.aggTypes.buckets.ranges.rangesFormatMessageArrowRight', {
|
||||
defaultMessage: '{from} → {to}',
|
||||
values: {
|
||||
from: fromValue,
|
||||
to: toValue,
|
||||
},
|
||||
});
|
||||
}
|
||||
return i18n.translate('data.aggTypes.buckets.ranges.rangesFormatMessage', {
|
||||
defaultMessage: '{gte} {from} and {lt} {to}',
|
||||
values: {
|
||||
gte,
|
||||
from: fromValue,
|
||||
lt,
|
||||
to: toValue,
|
||||
},
|
||||
});
|
||||
});
|
||||
return new RangeFormat();
|
||||
},
|
||||
date_range: () => {
|
||||
const nestedFormatter = params as SerializedFieldFormat;
|
||||
const DateRangeFormat = FieldFormat.from((range: DateRangeKey) => {
|
||||
const format = getFieldFormat({
|
||||
id: nestedFormatter.id,
|
||||
params: nestedFormatter.params,
|
||||
});
|
||||
return convertDateRangeToString(range, format.convert.bind(format));
|
||||
});
|
||||
return new DateRangeFormat();
|
||||
},
|
||||
ip_range: () => {
|
||||
const nestedFormatter = params as SerializedFieldFormat;
|
||||
const IpRangeFormat = FieldFormat.from((range: IpRangeKey) => {
|
||||
const format = getFieldFormat({
|
||||
id: nestedFormatter.id,
|
||||
params: nestedFormatter.params,
|
||||
});
|
||||
return convertIPRangeToString(range, format.convert.bind(format));
|
||||
});
|
||||
return new IpRangeFormat();
|
||||
},
|
||||
terms: () => {
|
||||
const convert = (val: string, type: FieldFormatsContentType) => {
|
||||
const format = getFieldFormat({ id: params.id, params });
|
||||
|
||||
if (val === '__other__') {
|
||||
return params.otherBucketLabel;
|
||||
}
|
||||
if (val === '__missing__') {
|
||||
return params.missingBucketLabel;
|
||||
}
|
||||
|
||||
return format.convert(val, type);
|
||||
};
|
||||
|
||||
return {
|
||||
convert,
|
||||
getConverterFor: (type: FieldFormatsContentType) => (val: string) => convert(val, type),
|
||||
} as IFieldFormat;
|
||||
},
|
||||
};
|
||||
|
||||
if (!id || !(id in customFormats)) {
|
||||
return getFieldFormat(mapping);
|
||||
}
|
||||
|
||||
return customFormats[id]();
|
||||
};
|
||||
}
|
|
@ -10,7 +10,7 @@ export * from './calculate_auto_time_expression';
|
|||
export { getNumberHistogramIntervalByDatatableColumn } from './get_number_histogram_interval';
|
||||
export { getDateHistogramMetaDataByDatatableColumn } from './get_date_histogram_meta';
|
||||
export * from './date_interval_utils';
|
||||
export * from './get_format_with_aggs';
|
||||
export * from './get_aggs_formats';
|
||||
export * from './ip_address';
|
||||
export * from './prop_filter';
|
||||
export * from './to_angular_json';
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
*/
|
||||
|
||||
import { CoreSetup } from 'src/core/public';
|
||||
import { deserializeFieldFormat } from './utils/deserialize';
|
||||
import { baseFormattersPublic } from './constants';
|
||||
import { DataPublicPluginStart, fieldFormats } from '..';
|
||||
import { fieldFormats } from '..';
|
||||
|
||||
export const getFieldFormatsRegistry = (core: CoreSetup) => {
|
||||
const fieldFormatsRegistry = new fieldFormats.FieldFormatsRegistry();
|
||||
|
@ -17,9 +16,5 @@ export const getFieldFormatsRegistry = (core: CoreSetup) => {
|
|||
|
||||
fieldFormatsRegistry.init(getConfig, {}, baseFormattersPublic);
|
||||
|
||||
fieldFormatsRegistry.deserialize = deserializeFieldFormat.bind(
|
||||
fieldFormatsRegistry as DataPublicPluginStart['fieldFormats']
|
||||
);
|
||||
|
||||
return fieldFormatsRegistry;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
import { CoreSetup } from 'src/core/public';
|
||||
import { FieldFormatsRegistry, UI_SETTINGS } from '../../common';
|
||||
import { deserializeFieldFormat } from './utils/deserialize';
|
||||
import { FormatFactory } from '../../common/field_formats/utils';
|
||||
import { baseFormattersPublic } from './constants';
|
||||
|
||||
|
@ -40,10 +39,6 @@ export class FieldFormatsService {
|
|||
}
|
||||
|
||||
public start() {
|
||||
this.fieldFormatsRegistry.deserialize = deserializeFieldFormat.bind(
|
||||
this.fieldFormatsRegistry as FieldFormatsStart
|
||||
);
|
||||
|
||||
return this.fieldFormatsRegistry as FieldFormatsStart;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,48 +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 { identity } from 'lodash';
|
||||
|
||||
import { SerializedFieldFormat } from '../../../../expressions/common/types';
|
||||
|
||||
import { FieldFormat } from '../../../common';
|
||||
import { FormatFactory } from '../../../common/field_formats/utils';
|
||||
import { getFormatWithAggs } from '../../../common/search/aggs';
|
||||
import { DataPublicPluginStart, IFieldFormat } from '../../../public';
|
||||
import { getUiSettings } from '../../../public/services';
|
||||
|
||||
const getConfig = (key: string, defaultOverride?: any): any =>
|
||||
getUiSettings().get(key, defaultOverride);
|
||||
const DefaultFieldFormat = FieldFormat.from(identity);
|
||||
|
||||
export const deserializeFieldFormat: FormatFactory = function (
|
||||
this: DataPublicPluginStart['fieldFormats'],
|
||||
serializedFieldFormat?: SerializedFieldFormat
|
||||
) {
|
||||
if (!serializedFieldFormat) {
|
||||
return new DefaultFieldFormat();
|
||||
}
|
||||
|
||||
const getFormat = (mapping: SerializedFieldFormat): IFieldFormat => {
|
||||
const { id, params = {} } = mapping;
|
||||
if (id) {
|
||||
const Format = this.getType(id);
|
||||
|
||||
if (Format) {
|
||||
return new Format(params, getConfig);
|
||||
}
|
||||
}
|
||||
|
||||
return new DefaultFieldFormat();
|
||||
};
|
||||
|
||||
// decorate getFormat to handle custom types created by aggs
|
||||
const getFieldFormat = getFormatWithAggs(getFormat);
|
||||
|
||||
return getFieldFormat(serializedFieldFormat);
|
||||
};
|
|
@ -50,6 +50,7 @@ import { getIndexPatternLoad } from './index_patterns/expressions';
|
|||
import { UsageCollectionSetup } from '../../usage_collection/public';
|
||||
import { getTableViewDescription } from './utils/table_inspector_view';
|
||||
import { NowProvider, NowProviderInternalContract } from './now_provider';
|
||||
import { getAggsFormats } from '../common';
|
||||
|
||||
export class DataPublicPlugin
|
||||
implements
|
||||
|
@ -71,6 +72,7 @@ export class DataPublicPlugin
|
|||
this.searchService = new SearchService(initializerContext);
|
||||
this.queryService = new QueryService();
|
||||
this.fieldFormatsService = new FieldFormatsService();
|
||||
|
||||
this.autocomplete = new AutocompleteService(initializerContext);
|
||||
this.storage = new Storage(window.localStorage);
|
||||
this.nowProvider = new NowProvider();
|
||||
|
@ -113,13 +115,20 @@ export class DataPublicPlugin
|
|||
}))
|
||||
);
|
||||
|
||||
const fieldFormats = this.fieldFormatsService.setup(core);
|
||||
fieldFormats.register(
|
||||
getAggsFormats((serializedFieldFormat) =>
|
||||
startServices().self.fieldFormats.deserialize(serializedFieldFormat)
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
autocomplete: this.autocomplete.setup(core, {
|
||||
timefilter: queryService.timefilter,
|
||||
usageCollection,
|
||||
}),
|
||||
search: searchService,
|
||||
fieldFormats: this.fieldFormatsService.setup(core),
|
||||
fieldFormats,
|
||||
query: queryService,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -988,6 +988,7 @@ export abstract class FieldFormat {
|
|||
// Warning: (ae-forgotten-export) The symbol "FieldFormatConvertFunction" needs to be exported by the entry point index.d.ts
|
||||
getConverterFor(contentType?: FieldFormatsContentType): FieldFormatConvertFunction;
|
||||
getParamDefaults(): Record<string, any>;
|
||||
static hidden: boolean;
|
||||
// Warning: (ae-forgotten-export) The symbol "HtmlContextTypeConvert" needs to be exported by the entry point index.d.ts
|
||||
htmlConvert: HtmlContextTypeConvert | undefined;
|
||||
static id: string;
|
||||
|
@ -1031,6 +1032,7 @@ export type FieldFormatId = FIELD_FORMAT_IDS | string;
|
|||
export type FieldFormatInstanceType = (new (params?: any, getConfig?: FieldFormatsGetConfigFn) => FieldFormat) & {
|
||||
id: FieldFormatId;
|
||||
title: string;
|
||||
hidden?: boolean;
|
||||
fieldType: string | string[];
|
||||
};
|
||||
|
||||
|
@ -2728,7 +2730,7 @@ export interface WaitUntilNextSessionCompletesOptions {
|
|||
// src/plugins/data/public/deprecated.ts:93:23 - (ae-forgotten-export) The symbol "changeTimeFilter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/deprecated.ts:93:23 - (ae-forgotten-export) The symbol "convertRangeFilterToTimeRangeString" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/deprecated.ts:93:23 - (ae-forgotten-export) The symbol "extractTimeFilter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/field_formats/field_formats_service.ts:56:3 - (ae-forgotten-export) The symbol "FormatFactory" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/field_formats/field_formats_service.ts:51:3 - (ae-forgotten-export) The symbol "FormatFactory" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:57:26 - (ae-forgotten-export) The symbol "FieldFormatsRegistry" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:57:26 - (ae-forgotten-export) The symbol "BoolFormat" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/data/public/index.ts:57:26 - (ae-forgotten-export) The symbol "BytesFormat" needs to be exported by the entry point index.d.ts
|
||||
|
|
Loading…
Reference in a new issue