diff --git a/src/legacy/core_plugins/data/public/search/aggs/buckets/date_range.ts b/src/legacy/core_plugins/data/public/search/aggs/buckets/date_range.ts
index 40ef7329dee6b..1dc24ca80035c 100644
--- a/src/legacy/core_plugins/data/public/search/aggs/buckets/date_range.ts
+++ b/src/legacy/core_plugins/data/public/search/aggs/buckets/date_range.ts
@@ -20,21 +20,19 @@ import { get } from 'lodash';
import moment from 'moment-timezone';
import { i18n } from '@kbn/i18n';
import { npStart } from 'ui/new_platform';
+import { convertDateRangeToString, DateRangeKey } from './lib/date_range';
import { BUCKET_TYPES } from './bucket_agg_types';
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { createFilterDateRange } from './create_filter/date_range';
import { KBN_FIELD_TYPES, fieldFormats } from '../../../../../../../plugins/data/public';
+export { convertDateRangeToString, DateRangeKey };
+
const dateRangeTitle = i18n.translate('data.search.aggs.buckets.dateRangeTitle', {
defaultMessage: 'Date Range',
});
-export interface DateRangeKey {
- from: number;
- to: number;
-}
-
export const dateRangeBucketAgg = new BucketAggType({
name: BUCKET_TYPES.DATE_RANGE,
title: dateRangeTitle,
@@ -106,16 +104,3 @@ export const dateRangeBucketAgg = new BucketAggType({
},
],
});
-
-export const convertDateRangeToString = (
- { from, to }: DateRangeKey,
- format: (val: any) => string
-) => {
- if (!from) {
- return 'Before ' + format(to);
- } else if (!to) {
- return 'After ' + format(from);
- } else {
- return format(from) + ' to ' + format(to);
- }
-};
diff --git a/src/legacy/core_plugins/data/public/search/aggs/buckets/ip_range.ts b/src/legacy/core_plugins/data/public/search/aggs/buckets/ip_range.ts
index e5497bef49165..91bdf53e7f809 100644
--- a/src/legacy/core_plugins/data/public/search/aggs/buckets/ip_range.ts
+++ b/src/legacy/core_plugins/data/public/search/aggs/buckets/ip_range.ts
@@ -20,21 +20,19 @@
import { noop, map, omit, isNull } from 'lodash';
import { i18n } from '@kbn/i18n';
import { npStart } from 'ui/new_platform';
+import { IpRangeKey, convertIPRangeToString } from './lib/ip_range';
import { BucketAggType } from './_bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
// @ts-ignore
import { createFilterIpRange } from './create_filter/ip_range';
import { KBN_FIELD_TYPES, fieldFormats } from '../../../../../../../plugins/data/public';
+export { IpRangeKey, convertIPRangeToString };
const ipRangeTitle = i18n.translate('data.search.aggs.buckets.ipRangeTitle', {
defaultMessage: 'IPv4 Range',
});
-export type IpRangeKey =
- | { type: 'mask'; mask: string }
- | { type: 'range'; from: string; to: string };
-
export const ipRangeBucketAgg = new BucketAggType({
name: BUCKET_TYPES.IP_RANGE,
title: ipRangeTitle,
@@ -97,13 +95,3 @@ export const ipRangeBucketAgg = new BucketAggType({
},
],
});
-
-export const convertIPRangeToString = (range: IpRangeKey, format: (val: any) => string) => {
- if (range.type === 'mask') {
- return format(range.mask);
- }
- const from = range.from ? format(range.from) : '-Infinity';
- const to = range.to ? format(range.to) : 'Infinity';
-
- return `${from} to ${to}`;
-};
diff --git a/src/legacy/core_plugins/data/public/search/aggs/buckets/lib/date_range.ts b/src/legacy/core_plugins/data/public/search/aggs/buckets/lib/date_range.ts
new file mode 100644
index 0000000000000..01b853fc669b5
--- /dev/null
+++ b/src/legacy/core_plugins/data/public/search/aggs/buckets/lib/date_range.ts
@@ -0,0 +1,36 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export interface DateRangeKey {
+ from: number;
+ to: number;
+}
+
+export const convertDateRangeToString = (
+ { from, to }: DateRangeKey,
+ format: (val: any) => string
+) => {
+ if (!from) {
+ return 'Before ' + format(to);
+ } else if (!to) {
+ return 'After ' + format(from);
+ } else {
+ return format(from) + ' to ' + format(to);
+ }
+};
diff --git a/src/legacy/core_plugins/data/public/search/aggs/buckets/lib/ip_range.ts b/src/legacy/core_plugins/data/public/search/aggs/buckets/lib/ip_range.ts
new file mode 100644
index 0000000000000..be1ac28934c7c
--- /dev/null
+++ b/src/legacy/core_plugins/data/public/search/aggs/buckets/lib/ip_range.ts
@@ -0,0 +1,32 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export type IpRangeKey =
+ | { type: 'mask'; mask: string }
+ | { type: 'range'; from: string; to: string };
+
+export const convertIPRangeToString = (range: IpRangeKey, format: (val: any) => string) => {
+ if (range.type === 'mask') {
+ return format(range.mask);
+ }
+ const from = range.from ? format(range.from) : '-Infinity';
+ const to = range.to ? format(range.to) : 'Infinity';
+
+ return `${from} to ${to}`;
+};
diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx
index 32c99f68a066e..6a466c9cd0211 100644
--- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx
+++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx
@@ -22,6 +22,10 @@ import { shallow } from 'enzyme';
import { Vis } from 'src/legacy/core_plugins/visualizations/public';
import { MetricVisComponent, MetricVisComponentProps } from './metric_vis_component';
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import { npStart } from 'ui/new_platform';
+import { fieldFormats } from '../../../../../plugins/data/public';
+import { identity } from 'lodash';
jest.mock('ui/new_platform');
@@ -62,6 +66,12 @@ describe('MetricVisComponent', function() {
return shallow();
};
+ beforeAll(() => {
+ (npStart.plugins.data.fieldFormats.deserialize as jest.Mock).mockImplementation(() => {
+ return new (fieldFormats.FieldFormat.from(identity))();
+ });
+ });
+
it('should render component', () => {
expect(getComponent().exists()).toBe(true);
});
diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts
index 28565e0181b84..15cd920b79e4a 100644
--- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts
+++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts
@@ -44,6 +44,9 @@ describe('metric_vis - createMetricVisTypeDefinition', () => {
(npStart.plugins.data.fieldFormats.getType as jest.Mock).mockImplementation(() => {
return fieldFormats.UrlFormat;
});
+ (npStart.plugins.data.fieldFormats.deserialize as jest.Mock).mockImplementation(mapping => {
+ return new fieldFormats.UrlFormat(mapping ? mapping.params : {});
+ });
});
const setup = () => {
diff --git a/src/legacy/core_plugins/vis_type_vislib/public/legacy_imports.ts b/src/legacy/core_plugins/vis_type_vislib/public/legacy_imports.ts
index 3d04c04f9b1a6..9c79be98a320c 100644
--- a/src/legacy/core_plugins/vis_type_vislib/public/legacy_imports.ts
+++ b/src/legacy/core_plugins/vis_type_vislib/public/legacy_imports.ts
@@ -18,10 +18,11 @@
*/
export { AggType, AggGroupNames, IAggConfig, IAggType, Schemas } from 'ui/agg_types';
-export { getFormat, getTableAggs } from 'ui/visualize/loader/pipeline_helpers/utilities';
+export { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities';
// @ts-ignore
export { tabifyAggResponse } from 'ui/agg_response/tabify';
// @ts-ignore
export { buildHierarchicalData } from 'ui/agg_response/hierarchical/build_hierarchical_data';
// @ts-ignore
export { buildPointSeriesData } from 'ui/agg_response/point_series/point_series';
+export { tabifyGetColumns } from '../../../ui/public/agg_response/tabify/_get_columns';
diff --git a/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx
index a170af33583df..c1563625c3b8c 100644
--- a/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx
+++ b/src/legacy/core_plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx
@@ -22,14 +22,24 @@ import { compact, uniq, map } from 'lodash';
import { i18n } from '@kbn/i18n';
import { EuiPopoverProps, EuiIcon, keyCodes, htmlIdGenerator } from '@elastic/eui';
+import { IAggConfig } from '../../../../../data/public';
// @ts-ignore
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { createFiltersFromEvent } from '../../../../../data/public/actions/filters/create_filters_from_event';
import { CUSTOM_LEGEND_VIS_TYPES, LegendItem } from './models';
import { VisLegendItem } from './legend_item';
import { getPieNames } from './pie_utils';
-import { getTableAggs } from '../../../legacy_imports';
+
+import { Vis } from '../../../../../visualizations/public';
+import { tabifyGetColumns } from '../../../legacy_imports';
+
+const getTableAggs = (vis: Vis): IAggConfig[] => {
+ if (!vis.aggs || !vis.aggs.getResponseAggs) {
+ return [];
+ }
+ const columns = tabifyGetColumns(vis.aggs.getResponseAggs(), !vis.isHierarchical());
+ return columns.map(c => c.aggConfig);
+};
export interface VisLegendProps {
vis: any;
diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts
index 7228e506accb9..cb25c66dfd2fe 100644
--- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts
+++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts
@@ -17,150 +17,15 @@
* under the License.
*/
-import { i18n } from '@kbn/i18n';
-import { identity } from 'lodash';
-import { IAggConfig } from 'ui/agg_types';
import { npStart } from 'ui/new_platform';
-import { SerializedFieldFormat } from 'src/plugins/expressions/public';
-import {
- fieldFormats,
- IFieldFormat,
- FieldFormatId,
- FieldFormatsContentType,
-} from '../../../../../../plugins/data/public';
-import { Vis } from '../../../../../core_plugins/visualizations/public';
+import { fieldFormats, IFieldFormat } from '../../../../../../plugins/data/public';
+import { SerializedFieldFormat } from '../../../../../../plugins/expressions/common/types';
-import { tabifyGetColumns } from '../../../agg_response/tabify/_get_columns';
-import { DateRangeKey, convertDateRangeToString } from '../../../agg_types';
-import { IpRangeKey, convertIPRangeToString } from '../../../agg_types';
+type FormatFactory = (mapping?: SerializedFieldFormat) => IFieldFormat;
-interface TermsFieldFormatParams {
- otherBucketLabel: string;
- missingBucketLabel: string;
- id: string;
-}
-
-function isTermsFieldFormat(
- serializedFieldFormat: SerializedFieldFormat
-): serializedFieldFormat is SerializedFieldFormat {
- return serializedFieldFormat.id === 'terms';
-}
-
-const getConfig = (key: string, defaultOverride?: any): any =>
- npStart.core.uiSettings.get(key, defaultOverride);
-const DefaultFieldFormat = fieldFormats.FieldFormat.from(identity);
-
-const getFieldFormat = (id?: FieldFormatId, params: object = {}): IFieldFormat => {
- const fieldFormatsService = npStart.plugins.data.fieldFormats;
-
- if (id) {
- const Format = fieldFormatsService.getType(id);
-
- if (Format) {
- return new Format(params, getConfig);
- }
- }
-
- return new DefaultFieldFormat();
-};
-
-export const createFormat = (agg: IAggConfig): SerializedFieldFormat => {
- const format: SerializedFieldFormat = agg.params.field ? agg.params.field.format.toJSON() : {};
- const formats: Record SerializedFieldFormat> = {
- date_range: () => ({ id: 'date_range', params: format }),
- ip_range: () => ({ id: 'ip_range', params: format }),
- percentile_ranks: () => ({ id: 'percent' }),
- count: () => ({ id: 'number' }),
- cardinality: () => ({ id: 'number' }),
- date_histogram: () => ({
- id: 'date',
- params: {
- pattern: (agg as any).buckets.getScaledDateFormat(),
- },
- }),
- terms: () => ({
- id: 'terms',
- params: {
- id: format.id,
- otherBucketLabel: agg.params.otherBucketLabel,
- missingBucketLabel: agg.params.missingBucketLabel,
- ...format.params,
- },
- }),
- range: () => ({
- id: 'range',
- params: { id: format.id, ...format.params },
- }),
- };
-
- return formats[agg.type.name] ? formats[agg.type.name]() : format;
-};
-
-export type FormatFactory = (mapping?: SerializedFieldFormat) => IFieldFormat;
-
-export const getFormat: FormatFactory = mapping => {
- if (!mapping) {
- return new DefaultFieldFormat();
- }
- const { id } = mapping;
- if (id === 'range') {
- const RangeFormat = fieldFormats.FieldFormat.from((range: any) => {
- const format = getFieldFormat(id, mapping.params);
- const gte = '\u2265';
- const lt = '\u003c';
- return i18n.translate('common.ui.aggTypes.rangesFormatMessage', {
- defaultMessage: '{gte} {from} and {lt} {to}',
- values: {
- gte,
- from: format.convert(range.gte),
- lt,
- to: format.convert(range.lt),
- },
- });
- });
- return new RangeFormat();
- } else if (id === 'date_range') {
- const nestedFormatter = mapping.params as SerializedFieldFormat;
- const DateRangeFormat = fieldFormats.FieldFormat.from((range: DateRangeKey) => {
- const format = getFieldFormat(nestedFormatter.id, nestedFormatter.params);
- return convertDateRangeToString(range, format.convert.bind(format));
- });
- return new DateRangeFormat();
- } else if (id === 'ip_range') {
- const nestedFormatter = mapping.params as SerializedFieldFormat;
- const IpRangeFormat = fieldFormats.FieldFormat.from((range: IpRangeKey) => {
- const format = getFieldFormat(nestedFormatter.id, nestedFormatter.params);
- return convertIPRangeToString(range, format.convert.bind(format));
- });
- return new IpRangeFormat();
- } else if (isTermsFieldFormat(mapping) && mapping.params) {
- const { params } = mapping;
- const convert = (val: string, type: FieldFormatsContentType) => {
- const format = getFieldFormat(params.id, mapping.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;
- } else {
- return getFieldFormat(id, mapping.params);
- }
+const createFormat = fieldFormats.serialize;
+const getFormat: FormatFactory = (mapping?) => {
+ return npStart.plugins.data.fieldFormats.deserialize(mapping as any);
};
-export const getTableAggs = (vis: Vis): IAggConfig[] => {
- if (!vis.aggs || !vis.aggs.getResponseAggs) {
- return [];
- }
- const columns = tabifyGetColumns(vis.aggs.getResponseAggs(), !vis.isHierarchical());
- return columns.map(c => c.aggConfig);
-};
+export { getFormat, createFormat, FormatFactory };
diff --git a/src/plugins/data/common/field_formats/field_formats_registry.ts b/src/plugins/data/common/field_formats/field_formats_registry.ts
index 6e4880a221c46..9fe9a31307b6a 100644
--- a/src/plugins/data/common/field_formats/field_formats_registry.ts
+++ b/src/plugins/data/common/field_formats/field_formats_registry.ts
@@ -18,9 +18,9 @@
*/
// eslint-disable-next-line max-classes-per-file
-import { forOwn, isFunction, memoize } from 'lodash';
+import { forOwn, isFunction, memoize, identity } from 'lodash';
-import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../common';
+import { ES_FIELD_TYPES, IFieldFormat, KBN_FIELD_TYPES } from '../../common';
import {
FieldFormatsGetConfigFn,
@@ -32,12 +32,17 @@ import {
} from './types';
import { baseFormatters } from './constants/base_formatters';
import { FieldFormat } from './field_format';
+import { SerializedFieldFormat } from '../../../expressions/common/types';
export class FieldFormatsRegistry {
protected fieldFormats: Map = new Map();
protected defaultMap: Record = {};
protected metaParamsOptions: Record = {};
protected getConfig?: FieldFormatsGetConfigFn;
+ // overriden on the public contract
+ public deserialize: (mapping: SerializedFieldFormat) => IFieldFormat = () => {
+ return new (FieldFormat.from(identity))();
+ };
init(
getConfig: FieldFormatsGetConfigFn,
diff --git a/src/plugins/data/common/field_formats/index.ts b/src/plugins/data/common/field_formats/index.ts
index 0847ac0db745f..d7858966f2620 100644
--- a/src/plugins/data/common/field_formats/index.ts
+++ b/src/plugins/data/common/field_formats/index.ts
@@ -41,7 +41,7 @@ export {
TruncateFormat,
} from './converters';
-export { getHighlightRequest } from './utils';
+export { getHighlightRequest, serializeFieldFormat } from './utils';
export { DEFAULT_CONVERTER_COLOR } from './constants/color_default';
export { FIELD_FORMAT_IDS } from './types';
diff --git a/src/plugins/data/common/field_formats/utils/index.ts b/src/plugins/data/common/field_formats/utils/index.ts
index 81b33115a44bb..3832c941ffad7 100644
--- a/src/plugins/data/common/field_formats/utils/index.ts
+++ b/src/plugins/data/common/field_formats/utils/index.ts
@@ -17,5 +17,11 @@
* under the License.
*/
+import { SerializedFieldFormat } from '../../../../expressions/common/types';
+import { IFieldFormat } from '../index';
+
export { asPrettyString } from './as_pretty_string';
export { getHighlightHtml, getHighlightRequest } from './highlight';
+export { serializeFieldFormat } from './serialize';
+
+export type FormatFactory = (mapping?: SerializedFieldFormat) => IFieldFormat;
diff --git a/src/plugins/data/common/field_formats/utils/serialize.ts b/src/plugins/data/common/field_formats/utils/serialize.ts
new file mode 100644
index 0000000000000..9931f55c30a9e
--- /dev/null
+++ b/src/plugins/data/common/field_formats/utils/serialize.ts
@@ -0,0 +1,53 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { IAggConfig } from '../../../../../legacy/ui/public/agg_types';
+import { SerializedFieldFormat } from '../../../../expressions/common/types';
+
+export const serializeFieldFormat = (agg: IAggConfig): SerializedFieldFormat => {
+ const format: SerializedFieldFormat = agg.params.field ? agg.params.field.format.toJSON() : {};
+ const formats: Record SerializedFieldFormat> = {
+ date_range: () => ({ id: 'date_range', params: format }),
+ ip_range: () => ({ id: 'ip_range', params: format }),
+ percentile_ranks: () => ({ id: 'percent' }),
+ count: () => ({ id: 'number' }),
+ cardinality: () => ({ id: 'number' }),
+ date_histogram: () => ({
+ id: 'date',
+ params: {
+ pattern: (agg as any).buckets.getScaledDateFormat(),
+ },
+ }),
+ terms: () => ({
+ id: 'terms',
+ params: {
+ id: format.id,
+ otherBucketLabel: agg.params.otherBucketLabel,
+ missingBucketLabel: agg.params.missingBucketLabel,
+ ...format.params,
+ },
+ }),
+ range: () => ({
+ id: 'range',
+ params: { id: format.id, ...format.params },
+ }),
+ };
+
+ return formats[agg.type.name] ? formats[agg.type.name]() : format;
+};
diff --git a/src/plugins/data/public/field_formats/field_formats_service.ts b/src/plugins/data/public/field_formats/field_formats_service.ts
index 1c43ce2198645..785bedf9b35d3 100644
--- a/src/plugins/data/public/field_formats/field_formats_service.ts
+++ b/src/plugins/data/public/field_formats/field_formats_service.ts
@@ -19,6 +19,8 @@
import { CoreSetup } from 'src/core/public';
import { FieldFormatsRegistry } from '../../common/field_formats';
+import { deserializeFieldFormat } from './utils/deserialize';
+import { FormatFactory } from '../../common/field_formats/utils';
export class FieldFormatsService {
private readonly fieldFormatsRegistry: FieldFormatsRegistry = new FieldFormatsRegistry();
@@ -44,6 +46,10 @@ export class FieldFormatsService {
}
public start() {
+ this.fieldFormatsRegistry.deserialize = deserializeFieldFormat.bind(
+ this.fieldFormatsRegistry as FieldFormatsStart
+ );
+
return this.fieldFormatsRegistry as FieldFormatsStart;
}
}
@@ -52,4 +58,6 @@ export class FieldFormatsService {
export type FieldFormatsSetup = Pick;
/** @public */
-export type FieldFormatsStart = Omit;
+export type FieldFormatsStart = Omit & {
+ deserialize: FormatFactory;
+};
diff --git a/src/plugins/data/public/field_formats/utils/deserialize.ts b/src/plugins/data/public/field_formats/utils/deserialize.ts
new file mode 100644
index 0000000000000..c10ebfbe3eb1e
--- /dev/null
+++ b/src/plugins/data/public/field_formats/utils/deserialize.ts
@@ -0,0 +1,129 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { identity } from 'lodash';
+import { i18n } from '@kbn/i18n';
+import {
+ convertDateRangeToString,
+ DateRangeKey,
+} from '../../../../../legacy/core_plugins/data/public/search/aggs/buckets/lib/date_range';
+import {
+ convertIPRangeToString,
+ IpRangeKey,
+} from '../../../../../legacy/core_plugins/data/public/search/aggs/buckets/lib/ip_range';
+import { SerializedFieldFormat } from '../../../../expressions/common/types';
+import { FieldFormatId, FieldFormatsContentType, IFieldFormat } from '../..';
+import { FieldFormat } from '../../../common';
+import { DataPublicPluginStart } from '../../../public';
+import { getUiSettings } from '../../../public/services';
+import { FormatFactory } from '../../../common/field_formats/utils';
+
+interface TermsFieldFormatParams {
+ otherBucketLabel: string;
+ missingBucketLabel: string;
+ id: string;
+}
+
+function isTermsFieldFormat(
+ serializedFieldFormat: SerializedFieldFormat
+): serializedFieldFormat is SerializedFieldFormat {
+ return serializedFieldFormat.id === 'terms';
+}
+
+const getConfig = (key: string, defaultOverride?: any): any =>
+ getUiSettings().get(key, defaultOverride);
+const DefaultFieldFormat = FieldFormat.from(identity);
+
+const getFieldFormat = (
+ fieldFormatsService: DataPublicPluginStart['fieldFormats'],
+ id?: FieldFormatId,
+ params: object = {}
+): IFieldFormat => {
+ if (id) {
+ const Format = fieldFormatsService.getType(id);
+
+ if (Format) {
+ return new Format(params, getConfig);
+ }
+ }
+
+ return new DefaultFieldFormat();
+};
+
+export const deserializeFieldFormat: FormatFactory = function(
+ this: DataPublicPluginStart['fieldFormats'],
+ mapping?: SerializedFieldFormat
+) {
+ if (!mapping) {
+ return new DefaultFieldFormat();
+ }
+ const { id } = mapping;
+ if (id === 'range') {
+ const RangeFormat = FieldFormat.from((range: any) => {
+ const format = getFieldFormat(this, id, mapping.params);
+ const gte = '\u2265';
+ const lt = '\u003c';
+ return i18n.translate('data.aggTypes.buckets.ranges.rangesFormatMessage', {
+ defaultMessage: '{gte} {from} and {lt} {to}',
+ values: {
+ gte,
+ from: format.convert(range.gte),
+ lt,
+ to: format.convert(range.lt),
+ },
+ });
+ });
+ return new RangeFormat();
+ } else if (id === 'date_range') {
+ const nestedFormatter = mapping.params as SerializedFieldFormat;
+ const DateRangeFormat = FieldFormat.from((range: DateRangeKey) => {
+ const format = getFieldFormat(this, nestedFormatter.id, nestedFormatter.params);
+ return convertDateRangeToString(range, format.convert.bind(format));
+ });
+ return new DateRangeFormat();
+ } else if (id === 'ip_range') {
+ const nestedFormatter = mapping.params as SerializedFieldFormat;
+ const IpRangeFormat = FieldFormat.from((range: IpRangeKey) => {
+ const format = getFieldFormat(this, nestedFormatter.id, nestedFormatter.params);
+ return convertIPRangeToString(range, format.convert.bind(format));
+ });
+ return new IpRangeFormat();
+ } else if (isTermsFieldFormat(mapping) && mapping.params) {
+ const { params } = mapping;
+ const convert = (val: string, type: FieldFormatsContentType) => {
+ const format = getFieldFormat(this, params.id, mapping.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;
+ } else {
+ return getFieldFormat(this, id, mapping.params);
+ }
+};
diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts
index 32d421cf85604..cdc4167f545af 100644
--- a/src/plugins/data/public/index.ts
+++ b/src/plugins/data/public/index.ts
@@ -168,6 +168,7 @@ import {
UrlFormat,
StringFormat,
TruncateFormat,
+ serializeFieldFormat,
} from '../common/field_formats';
// Field formats helpers namespace:
@@ -175,6 +176,8 @@ export const fieldFormats = {
FieldFormat,
FieldFormatsRegistry, // exported only for tests. Consider mock.
+ serialize: serializeFieldFormat,
+
DEFAULT_CONVERTER_COLOR,
HTML_CONTEXT_TYPE,
TEXT_CONTEXT_TYPE,
diff --git a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts
index 103f9d385b3f9..b6ca91169a933 100644
--- a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts
+++ b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts
@@ -31,7 +31,7 @@ import { setNotifications, setFieldFormats } from '../../services';
// Temporary disable eslint, will be removed after moving to new platform folder
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { notificationServiceMock } from '../../../../../core/public/notifications/notifications_service.mock';
-import { FieldFormatsRegistry } from '../../../common/field_formats';
+import { FieldFormatsStart } from '../../field_formats';
jest.mock('../../../../kibana_utils/public', () => {
const originalModule = jest.requireActual('../../../../kibana_utils/public');
@@ -125,7 +125,8 @@ describe('IndexPattern', () => {
setNotifications(notifications);
setFieldFormats(({
getDefaultInstance: jest.fn(),
- } as unknown) as FieldFormatsRegistry);
+ deserialize: jest.fn() as any,
+ } as unknown) as FieldFormatsStart);
return create(indexPatternId).then((pattern: IndexPattern) => {
indexPattern = pattern;
diff --git a/src/plugins/data/public/mocks.ts b/src/plugins/data/public/mocks.ts
index 0a093644c3939..c723c34cd0a22 100644
--- a/src/plugins/data/public/mocks.ts
+++ b/src/plugins/data/public/mocks.ts
@@ -49,6 +49,7 @@ const fieldFormatsMock: IFieldFormatsRegistry = {
init: jest.fn(),
register: jest.fn(),
parseDefaultTypeMap: jest.fn(),
+ deserialize: jest.fn(),
};
const createSetupContract = (): Setup => {
diff --git a/src/plugins/data/public/ui/query_string_input/__snapshots__/query_string_input.test.tsx.snap b/src/plugins/data/public/ui/query_string_input/__snapshots__/query_string_input.test.tsx.snap
index eebbc63f6f1e4..990386687bade 100644
--- a/src/plugins/data/public/ui/query_string_input/__snapshots__/query_string_input.test.tsx.snap
+++ b/src/plugins/data/public/ui/query_string_input/__snapshots__/query_string_input.test.tsx.snap
@@ -173,6 +173,7 @@ exports[`QueryStringInput Should disable autoFocus on EuiFieldText when disableA
"hasQuerySuggestions": [MockFunction],
},
"fieldFormats": Object {
+ "deserialize": [MockFunction],
"getByFieldType": [MockFunction],
"getDefaultConfig": [MockFunction],
"getDefaultInstance": [MockFunction],
@@ -825,6 +826,7 @@ exports[`QueryStringInput Should disable autoFocus on EuiFieldText when disableA
"hasQuerySuggestions": [MockFunction],
},
"fieldFormats": Object {
+ "deserialize": [MockFunction],
"getByFieldType": [MockFunction],
"getDefaultConfig": [MockFunction],
"getDefaultInstance": [MockFunction],
@@ -1459,6 +1461,7 @@ exports[`QueryStringInput Should pass the query language to the language switche
"hasQuerySuggestions": [MockFunction],
},
"fieldFormats": Object {
+ "deserialize": [MockFunction],
"getByFieldType": [MockFunction],
"getDefaultConfig": [MockFunction],
"getDefaultInstance": [MockFunction],
@@ -2108,6 +2111,7 @@ exports[`QueryStringInput Should pass the query language to the language switche
"hasQuerySuggestions": [MockFunction],
},
"fieldFormats": Object {
+ "deserialize": [MockFunction],
"getByFieldType": [MockFunction],
"getDefaultConfig": [MockFunction],
"getDefaultInstance": [MockFunction],
@@ -2742,6 +2746,7 @@ exports[`QueryStringInput Should render the given query 1`] = `
"hasQuerySuggestions": [MockFunction],
},
"fieldFormats": Object {
+ "deserialize": [MockFunction],
"getByFieldType": [MockFunction],
"getDefaultConfig": [MockFunction],
"getDefaultInstance": [MockFunction],
@@ -3391,6 +3396,7 @@ exports[`QueryStringInput Should render the given query 1`] = `
"hasQuerySuggestions": [MockFunction],
},
"fieldFormats": Object {
+ "deserialize": [MockFunction],
"getByFieldType": [MockFunction],
"getDefaultConfig": [MockFunction],
"getDefaultInstance": [MockFunction],
diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts
index e8f422d94909f..3ee98a318de35 100644
--- a/src/plugins/data/server/index.ts
+++ b/src/plugins/data/server/index.ts
@@ -95,12 +95,15 @@ import {
UrlFormat,
StringFormat,
TruncateFormat,
+ serializeFieldFormat,
} from '../common/field_formats';
export const fieldFormats = {
FieldFormatsRegistry,
FieldFormat,
+ serializeFieldFormat,
+
BoolFormat,
BytesFormat,
ColorFormat,
diff --git a/src/test_utils/public/stub_field_formats.ts b/src/test_utils/public/stub_field_formats.ts
index 32bdca1eea258..5a20823134ebd 100644
--- a/src/test_utils/public/stub_field_formats.ts
+++ b/src/test_utils/public/stub_field_formats.ts
@@ -17,7 +17,8 @@
* under the License.
*/
import { CoreSetup } from 'kibana/public';
-import { fieldFormats } from '../../plugins/data/public';
+import { DataPublicPluginStart, fieldFormats } from '../../plugins/data/public';
+import { deserializeFieldFormat } from '../../plugins/data/public/field_formats/utils/deserialize';
export const getFieldFormatsRegistry = (core: CoreSetup) => {
const fieldFormatsRegistry = new fieldFormats.FieldFormatsRegistry();
@@ -25,5 +26,9 @@ export const getFieldFormatsRegistry = (core: CoreSetup) => {
fieldFormatsRegistry.init(getConfig, {});
+ fieldFormatsRegistry.deserialize = deserializeFieldFormat.bind(
+ fieldFormatsRegistry as DataPublicPluginStart['fieldFormats']
+ );
+
return fieldFormatsRegistry;
};
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index ffd780842552e..6b2dc984eefda 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -77,7 +77,6 @@
},
"messages": {
"common.ui.aggResponse.allDocsTitle": "すべてのドキュメント",
- "common.ui.aggTypes.rangesFormatMessage": "{gte} {from} と {lt} {to}",
"data.search.aggs.aggGroups.bucketsText": "バケット",
"data.search.aggs.aggGroups.metricsText": "メトリック",
"data.search.aggs.buckets.dateHistogramLabel": "{intervalDescription}ごとの {fieldName}",
@@ -13844,4 +13843,4 @@
"xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。",
"xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。"
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index d27dd65c03075..c4d94c31ecfdc 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -77,7 +77,6 @@
},
"messages": {
"common.ui.aggResponse.allDocsTitle": "所有文档",
- "common.ui.aggTypes.rangesFormatMessage": "{gte} {from} 且 {lt} {to}",
"data.search.aggs.aggGroups.bucketsText": "存储桶",
"data.search.aggs.aggGroups.metricsText": "指标",
"data.search.aggs.buckets.dateHistogramLabel": "{fieldName}/{intervalDescription}",
@@ -13843,4 +13842,4 @@
"xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "此字段必填。",
"xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。"
}
-}
\ No newline at end of file
+}