From 75d9d79e00d1b51b4496545d6c222543ef2c3202 Mon Sep 17 00:00:00 2001 From: Avinar-24 Date: Wed, 23 Oct 2019 16:00:05 +0300 Subject: [PATCH] Register utils in the new field formats --- src/legacy/core_plugins/data/public/plugin.ts | 44 +++- .../core_plugins/kibana/public/kibana.js | 1 - .../visualize_embeddable_factory.tsx | 2 - .../field_formats_provider/field_formats.ts | 223 ++++++++++++++++++ .../public/field_formats_provider/index.ts | 205 +--------------- 5 files changed, 265 insertions(+), 210 deletions(-) create mode 100644 src/plugins/data/public/field_formats_provider/field_formats.ts diff --git a/src/legacy/core_plugins/data/public/plugin.ts b/src/legacy/core_plugins/data/public/plugin.ts index 8a0a6a5e77466..af719e735a950 100644 --- a/src/legacy/core_plugins/data/public/plugin.ts +++ b/src/legacy/core_plugins/data/public/plugin.ts @@ -29,7 +29,22 @@ import { } from './shim/legacy_dependencies_plugin'; import { DataPublicPluginStart, - FieldFormatProviderRegister, + FieldFormatRegisty, + StaticLookupFormat, + NumberFormat, + SourceFormat, + BoolFormat, + ColorFormat, + DateFormat, + DateNanosFormat, + DurationFormat, + IpFormat, + PercentFormat, + RelativeDateFormat, + TruncateFormat, + BytesFormat, + StringFormat, + UrlFormat, } from '../../../../plugins/data/public'; import { initLegacyModule } from './shim/legacy_module'; import { IUiActionsSetup } from '../../../../plugins/ui_actions/public'; @@ -64,6 +79,7 @@ export interface DataSetup { timefilter: TimefilterSetup; indexPatterns: IndexPatternsSetup; filter: FilterSetup; + fieldFormats: FieldFormatRegisty; } /** @@ -104,10 +120,10 @@ export class DataPlugin private readonly timefilter: TimefilterService = new TimefilterService(); private setupApi!: DataSetup; + private fieldFormats!: FieldFormatRegisty; public setup(core: CoreSetup, { __LEGACY }: DataPluginSetupDependencies): DataSetup { const { uiSettings } = core; - const timefilterService = this.timefilter.setup({ uiSettings, store: __LEGACY.storage, @@ -115,11 +131,32 @@ export class DataPlugin const filterService = this.filter.setup({ uiSettings, }); + + this.fieldFormats = new FieldFormatRegisty(uiSettings); + this.fieldFormats.register([ + UrlFormat, + StringFormat, + NumberFormat, + BytesFormat, + TruncateFormat, + RelativeDateFormat, + PercentFormat, + IpFormat, + DurationFormat, + DateNanosFormat, + DateFormat, + ColorFormat, + BoolFormat, + SourceFormat, + StaticLookupFormat, + ]); + this.setupApi = { indexPatterns: this.indexPatterns.setup(), query: this.query.setup(), timefilter: timefilterService, filter: filterService, + fieldFormats: this.fieldFormats, }; return this.setupApi; @@ -130,14 +167,13 @@ export class DataPlugin { __LEGACY, data, uiActions }: DataPluginStartDependencies ): DataStart { const { uiSettings, http, notifications, savedObjects } = core; - const fieldFormats = new FieldFormatProviderRegister(uiSettings); const indexPatternsService = this.indexPatterns.start({ uiSettings, savedObjectsClient: savedObjects.client, http, notifications, - fieldFormats, + fieldFormats: this.fieldFormats, }); initLegacyModule(indexPatternsService.indexPatterns); diff --git a/src/legacy/core_plugins/kibana/public/kibana.js b/src/legacy/core_plugins/kibana/public/kibana.js index 6c809e84c8c84..edf90aee619da 100644 --- a/src/legacy/core_plugins/kibana/public/kibana.js +++ b/src/legacy/core_plugins/kibana/public/kibana.js @@ -31,7 +31,6 @@ import 'uiExports/visTypes'; import 'uiExports/visEditorTypes'; import 'uiExports/visualize'; import 'uiExports/savedObjectTypes'; -import 'uiExports/fieldFormats'; import 'uiExports/fieldFormatEditors'; import 'uiExports/navbarExtensions'; import 'uiExports/contextMenuActions'; diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx index 8448b65e0994e..39ef816f72447 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx +++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx @@ -17,14 +17,12 @@ * under the License. */ -import 'ui/registry/field_formats'; import 'uiExports/contextMenuActions'; import 'uiExports/devTools'; import 'uiExports/docViews'; import 'uiExports/embeddableFactories'; import 'uiExports/embeddableActions'; import 'uiExports/fieldFormatEditors'; -import 'uiExports/fieldFormats'; import 'uiExports/home'; import 'uiExports/indexManagement'; import 'uiExports/inspectorViews'; diff --git a/src/plugins/data/public/field_formats_provider/field_formats.ts b/src/plugins/data/public/field_formats_provider/field_formats.ts new file mode 100644 index 0000000000000..e547ec3ce3842 --- /dev/null +++ b/src/plugins/data/public/field_formats_provider/field_formats.ts @@ -0,0 +1,223 @@ +/* + * 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 { forOwn, isFunction, memoize } from 'lodash'; +import { UiSettingsClientContract } from 'kibana/public'; +import { FieldFormat } from '../../common/field_formats'; +import { FIELD_FORMATS_IDS } from './types'; +import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../common'; + +interface FieldType { + id: FIELD_FORMATS_IDS; + params: Record; + es?: boolean; +} + +export class FieldFormatRegisty { + private fieldFormats: Map; + private uiSettings: UiSettingsClientContract; + private getConfig: Function; + private defaultMap: { [key in ES_FIELD_TYPES | KBN_FIELD_TYPES]?: FieldType } & { + _default_: FieldType; + }; + + constructor(uiSettings: UiSettingsClientContract) { + this.fieldFormats = new Map(); + this.uiSettings = uiSettings; + this.getConfig = (key: string, override?: any) => this.uiSettings.get(key, override); + this.defaultMap = { + _default_: { id: FIELD_FORMATS_IDS.STRING, params: {} }, + }; + this.init(); + } + + init() { + this.parseDefaultTypeMap(this.uiSettings.get('format:defaultTypeMap')); + + this.uiSettings.getUpdate$().subscribe(({ key, newValue }) => { + if (key === 'format:defaultTypeMap') { + this.parseDefaultTypeMap(newValue); + } + }); + } + + /** + * Get the id of the default type for this field type + * using the format:defaultTypeMap config map + * + * @param {KBN_FIELD_TYPES} fieldType - the field type + * @param {ES_FIELD_TYPES[]} esTypes - Array of ES data types + * @return {FieldType} + */ + getDefaultConfig = (fieldType: KBN_FIELD_TYPES, esTypes: ES_FIELD_TYPES[]): FieldType => { + const type = this.getDefaultTypeName(fieldType, esTypes); + + return this.defaultMap[type] || this.defaultMap._default_; + }; + + /** + * Get a FieldFormat type (class) by its id. + * + * @param {FIELD_FORMATS_IDS} formatId - the format id + * @return {FieldFormat} + */ + getType = (formatId: FIELD_FORMATS_IDS): typeof FieldFormat => { + return this.fieldFormats.get(formatId) as typeof FieldFormat; + }; + + /** + * Get the default FieldFormat type (class) for + * a field type, using the format:defaultTypeMap. + * used by the field editor + * + * @param {KBN_FIELD_TYPES} fieldType + * @param {ES_FIELD_TYPES[]} esTypes - Array of ES data types + * @return {FieldFormat} + */ + getDefaultType = (fieldType: KBN_FIELD_TYPES, esTypes: ES_FIELD_TYPES[]): typeof FieldFormat => { + const config = this.getDefaultConfig(fieldType, esTypes) as FieldType; + + return this.getType(config.id); + }; + + /** + * Get the name of the default type for ES types like date_nanos + * using the format:defaultTypeMap config map + * + * @param {ES_FIELD_TYPES[]} esTypes - Array of ES data types + * @return {ES_FIELD_TYPES | String} + */ + getTypeNameByEsTypes = (esTypes: ES_FIELD_TYPES[]): ES_FIELD_TYPES | string => { + if (!Array.isArray(esTypes)) { + return ''; + } + + return esTypes.find(type => this.defaultMap[type] && this.defaultMap[type]!.es) || ''; + }; + + /** + * Get the default FieldFormat type name for + * a field type, using the format:defaultTypeMap. + * + * @param {KBN_FIELD_TYPES} fieldType + * @param {ES_FIELD_TYPES[]} esTypes + * @return {KBN_FIELD_TYPES | ES_FIELD_TYPES} + */ + getDefaultTypeName = ( + fieldType: KBN_FIELD_TYPES, + esTypes: ES_FIELD_TYPES[] + ): KBN_FIELD_TYPES | ES_FIELD_TYPES => { + const esType = this.getTypeNameByEsTypes(esTypes) as ES_FIELD_TYPES; + + return esType || fieldType; + }; + + /** + * Get the singleton instance of the FieldFormat type by its id. + * + * @param {FIELD_FORMATS_IDS} formatId + * @return {FieldFormat} + */ + getInstance = memoize( + (formatId: FIELD_FORMATS_IDS): FieldFormat => { + const DerivedFieldFormat = this.getType(formatId); + + if (!DerivedFieldFormat) { + throw new Error(`Field Format '${formatId}' not found!`); + } + + // @ts-ignore + return new DerivedFieldFormat({}, this.getConfig); + } + ); + + /** + * Get the default fieldFormat instance for a field format. + * + * @param {KBN_FIELD_TYPES} fieldType + * @param {ES_FIELD_TYPES[]} esTypes + * @return {FieldFormat} + */ + getDefaultInstancePlain(fieldType: KBN_FIELD_TYPES, esTypes: ES_FIELD_TYPES[]) { + const conf = this.getDefaultConfig(fieldType, esTypes) as FieldType; + const DerivedFieldFormat = this.getType(conf.id); + + // @ts-ignore + return new DerivedFieldFormat(conf.params, this.getConfig); + } + /** + * Returns a cache key built by the given variables for caching in memoized + * Where esType contains fieldType, fieldType is returned + * -> kibana types have a higher priority in that case + * -> would lead to failing tests that match e.g. date format with/without esTypes + * https://lodash.com/docs#memoize + * + * @param {KBN_FIELD_TYPES} fieldType + * @param {ES_FIELD_TYPES[]} esTypes + * @return {string} + */ + getDefaultInstanceCacheResolver(fieldType: KBN_FIELD_TYPES, esTypes: ES_FIELD_TYPES[]) { + // @ts-ignore + return Array.isArray(esTypes) && esTypes.indexOf(fieldType) === -1 + ? [fieldType, ...esTypes].join('-') + : fieldType; + } + + /** + * Get filtered list of field formats by format type + * + * @param {String} fieldType + * @return {FieldFormat[]} + */ + getByFieldType(fieldType: KBN_FIELD_TYPES) { + return [...this.fieldFormats.values()].filter( + format => format.fieldType.indexOf(fieldType) !== -1 + ); + } + + /** + * Get the default fieldFormat instance for a field format. + * It's a memoized function that builds and reads a cache + * + * @param {String} fieldType + * @param {String[]} esTypes + * @return {FieldFormat} + */ + getDefaultInstance = memoize(this.getDefaultInstancePlain, this.getDefaultInstanceCacheResolver); + + parseDefaultTypeMap(value: any) { + this.defaultMap = value; + forOwn(this, fn => { + if (isFunction(fn) && fn.cache) { + // clear all memoize caches + // @ts-ignore + fn.cache = new memoize.Cache(); + } + }); + } + + // any = DerivedFieldFormat + register = (fieldFormats: any[] = []) => { + fieldFormats.forEach(fieldFormat => { + this.fieldFormats.set(fieldFormat.id, fieldFormat); + }); + + return this; + }; +} diff --git a/src/plugins/data/public/field_formats_provider/index.ts b/src/plugins/data/public/field_formats_provider/index.ts index c3e8231d50614..ecaa0df8eab5d 100644 --- a/src/plugins/data/public/field_formats_provider/index.ts +++ b/src/plugins/data/public/field_formats_provider/index.ts @@ -17,206 +17,5 @@ * under the License. */ -import { forOwn, isFunction, memoize } from 'lodash'; -import { UiSettingsClientContract } from 'kibana/public'; -import { FieldFormat } from '../../common/field_formats'; -import { FIELD_FORMATS_IDS } from './types'; -import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../common'; - -interface FieldType { - id: FIELD_FORMATS_IDS; - params: Record; - es?: boolean; -} - -export class FieldFormatProviderRegister { - private fieldFormats: Map; - private uiSettings: UiSettingsClientContract; - private getConfig: Function; - private defaultMap: { [key in ES_FIELD_TYPES | KBN_FIELD_TYPES]?: FieldType } & { - _default_: FieldType; - }; - - constructor(uiSettings: UiSettingsClientContract) { - this.fieldFormats = new Map(); - this.uiSettings = uiSettings; - this.getConfig = (key: string, override?: any) => this.uiSettings.get(key, override); - this.defaultMap = { - _default_: { id: FIELD_FORMATS_IDS.STRING, params: {} }, - }; - this.init(); - } - - init() { - this.parseDefaultTypeMap(this.uiSettings.get('format:defaultTypeMap')); - - this.uiSettings.getUpdate$().subscribe(({ key, newValue }) => { - if (key === 'format:defaultTypeMap') { - this.parseDefaultTypeMap(newValue); - } - }); - } - - /** - * Get the id of the default type for this field type - * using the format:defaultTypeMap config map - * - * @param {KBN_FIELD_TYPES} fieldType - the field type - * @param {ES_FIELD_TYPES[]} esTypes - Array of ES data types - * @return {FieldType} - */ - getDefaultConfig = (fieldType: KBN_FIELD_TYPES, esTypes: ES_FIELD_TYPES[]): FieldType => { - const type = this.getDefaultTypeName(fieldType, esTypes); - - return this.defaultMap[type] || this.defaultMap._default_; - }; - - /** - * Get a FieldFormat type (class) by its id. - * - * @param {FIELD_FORMATS_IDS} formatId - the format id - * @return {FieldFormat} - */ - getType = (formatId: FIELD_FORMATS_IDS): typeof FieldFormat => { - return this.fieldFormats.get(formatId) as typeof FieldFormat; - }; - - /** - * Get the default FieldFormat type (class) for - * a field type, using the format:defaultTypeMap. - * used by the field editor - * - * @param {KBN_FIELD_TYPES} fieldType - * @param {ES_FIELD_TYPES[]} esTypes - Array of ES data types - * @return {FieldFormat} - */ - getDefaultType = (fieldType: KBN_FIELD_TYPES, esTypes: ES_FIELD_TYPES[]): typeof FieldFormat => { - const config = this.getDefaultConfig(fieldType, esTypes) as FieldType; - - return this.getType(config.id); - }; - - /** - * Get the name of the default type for ES types like date_nanos - * using the format:defaultTypeMap config map - * - * @param {ES_FIELD_TYPES[]} esTypes - Array of ES data types - * @return {ES_FIELD_TYPES | String} - */ - getTypeNameByEsTypes = (esTypes: ES_FIELD_TYPES[]): ES_FIELD_TYPES | string => { - if (!Array.isArray(esTypes)) { - return ''; - } - - return esTypes.find(type => this.defaultMap[type] && this.defaultMap[type]!.es) || ''; - }; - - /** - * Get the default FieldFormat type name for - * a field type, using the format:defaultTypeMap. - * - * @param {KBN_FIELD_TYPES} fieldType - * @param {ES_FIELD_TYPES[]} esTypes - * @return {KBN_FIELD_TYPES | ES_FIELD_TYPES} - */ - getDefaultTypeName = ( - fieldType: KBN_FIELD_TYPES, - esTypes: ES_FIELD_TYPES[] - ): KBN_FIELD_TYPES | ES_FIELD_TYPES => { - const esType = this.getTypeNameByEsTypes(esTypes) as ES_FIELD_TYPES; - - return esType || fieldType; - }; - - /** - * Get the singleton instance of the FieldFormat type by its id. - * - * @param {FIELD_FORMATS_IDS} formatId - * @return {FieldFormat} - */ - getInstance = memoize( - (formatId: FIELD_FORMATS_IDS): FieldFormat => { - const DerivedFieldFormat = this.getType(formatId); - - if (!DerivedFieldFormat) { - throw new Error(`Field Format '${formatId}' not found!`); - } - - // @ts-ignore - return new DerivedFieldFormat({}, this.getConfig); - } - ); - - /** - * Get the default fieldFormat instance for a field format. - * - * @param {KBN_FIELD_TYPES} fieldType - * @param {ES_FIELD_TYPES[]} esTypes - * @return {FieldFormat} - */ - getDefaultInstancePlain(fieldType: KBN_FIELD_TYPES, esTypes: ES_FIELD_TYPES[]) { - const conf = this.getDefaultConfig(fieldType, esTypes) as FieldType; - const DerivedFieldFormat = this.getType(conf.id); - - // @ts-ignore - return new DerivedFieldFormat(conf.params, this.getConfig); - } - /** - * Returns a cache key built by the given variables for caching in memoized - * Where esType contains fieldType, fieldType is returned - * -> kibana types have a higher priority in that case - * -> would lead to failing tests that match e.g. date format with/without esTypes - * https://lodash.com/docs#memoize - * - * @param {KBN_FIELD_TYPES} fieldType - * @param {ES_FIELD_TYPES[]} esTypes - * @return {string} - */ - getDefaultInstanceCacheResolver(fieldType: KBN_FIELD_TYPES, esTypes: ES_FIELD_TYPES[]) { - // @ts-ignore - return Array.isArray(esTypes) && esTypes.indexOf(fieldType) === -1 - ? [fieldType, ...esTypes].join('-') - : fieldType; - } - - /** - * Get filtered list of field formats by format type - * - * @param {String} fieldType - * @return {FieldFormat[]} - */ - getByFieldType(fieldType: KBN_FIELD_TYPES) { - return [...this.fieldFormats.values()].filter( - format => format.fieldType.indexOf(fieldType) !== -1 - ); - } - - /** - * Get the default fieldFormat instance for a field format. - * It's a memoized function that builds and reads a cache - * - * @param {String} fieldType - * @param {String[]} esTypes - * @return {FieldFormat} - */ - getDefaultInstance = memoize(this.getDefaultInstancePlain, this.getDefaultInstanceCacheResolver); - - parseDefaultTypeMap(value: any) { - this.defaultMap = value; - forOwn(this, fn => { - if (isFunction(fn) && fn.cache) { - // clear all memoize caches - // @ts-ignore - fn.cache = new memoize.Cache(); - } - }); - } - - register = (module: Function) => { - const fieldFormat = module(FieldFormat); - - this.fieldFormats.set(fieldFormat.id, fieldFormat); - - return this; - }; -} +export { FieldFormatRegisty } from './field_formats'; +export { FIELD_FORMATS_IDS } from './types';