Skip to content

Commit

Permalink
Display changed field formats without requiring hard page refresh. (#…
Browse files Browse the repository at this point in the history
…53746) (#53771)

* Display changed field formats without requiring hard page refresh.

* Update src/plugins/data/public/field_formats_provider/field_formats.ts

Co-Authored-By: Vadim Dalecky <streamich@users.noreply.github.com>

* fix PR commetns

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Vadim Dalecky <streamich@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Vadim Dalecky <streamich@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 23, 2019
1 parent baebbeb commit 2c6ed6d
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import { memoize, noop } from 'lodash';
import moment from 'moment-timezone';
import { KBN_FIELD_TYPES } from '../../kbn_field_types/types';
import { FieldFormat } from '../field_format';
import { FieldFormat, IFieldFormatMetaParams } from '../field_format';
import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types';

export class DateFormat extends FieldFormat {
Expand All @@ -32,7 +32,7 @@ export class DateFormat extends FieldFormat {
private memoizedPattern: string = '';
private timeZone: string = '';

constructor(params: Record<string, any>, getConfig: Function) {
constructor(params: IFieldFormatMetaParams, getConfig: Function) {
super(params, getConfig);

this.memoizedConverter = memoize((val: any) => {
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/data/common/field_formats/converters/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n';
import { escape, memoize } from 'lodash';
import { getHighlightHtml } from '../utils';
import { KBN_FIELD_TYPES } from '../../kbn_field_types/types';
import { FieldFormat } from '../field_format';
import { FieldFormat, IFieldFormatMetaParams } from '../field_format';
import { TextContextTypeConvert, HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types';

const templateMatchRE = /{{([\s\S]+?)}}/g;
Expand Down Expand Up @@ -64,7 +64,7 @@ export class UrlFormat extends FieldFormat {
];
static urlTypes = URL_TYPES;

constructor(params: Record<string, any>) {
constructor(params: IFieldFormatMetaParams) {
super(params);
this.compileTemplate = memoize(this.compileTemplate);
}
Expand Down
11 changes: 10 additions & 1 deletion src/plugins/data/common/field_formats/field_format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ import { HtmlContextTypeConvert, TextContextTypeConvert } from './types';

const DEFAULT_CONTEXT_TYPE = TEXT_CONTEXT_TYPE;

export interface IFieldFormatMetaParams {
[key: string]: any;
parsedUrl?: {
origin: string;
pathname?: string;
basePath?: string;
};
}

export abstract class FieldFormat {
/**
* @property {string} - Field Format Id
Expand Down Expand Up @@ -90,7 +99,7 @@ export abstract class FieldFormat {
protected readonly _params: any;
protected getConfig: Function | undefined;

constructor(_params: Record<string, any> = {}, getConfig?: Function) {
constructor(_params: IFieldFormatMetaParams = {}, getConfig?: Function) {
this._params = _params;

if (getConfig) {
Expand Down
7 changes: 6 additions & 1 deletion src/plugins/data/common/field_formats/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
*/

export { HTML_CONTEXT_TYPE, TEXT_CONTEXT_TYPE } from './content_types';
export { FieldFormat, IFieldFormatType, IFieldFormatId } from './field_format';
export {
FieldFormat,
IFieldFormatType,
IFieldFormatId,
IFieldFormatMetaParams,
} from './field_format';
export { getHighlightRequest, asPrettyString, getHighlightHtml } from './utils';
export * from './converters';
export * from './constants';
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import { CoreSetup, IUiSettingsClient } from 'kibana/public';

import { FieldFormatRegisty } from './field_formats';
import {
BoolFormat,
IFieldFormatType,
PercentFormat,
BoolFormat,
StringFormat,
} from '../../common/field_formats';
import { coreMock } from '../../../../core/public/mocks';
import { KBN_FIELD_TYPES } from '../../common';

const getValueOfPrivateField = (instance: any, field: string) => instance[field];
const getUiSettingsMock = (data: any): IUiSettingsClient['get'] => () => data;
Expand Down Expand Up @@ -115,12 +116,12 @@ describe('FieldFormatRegisty', () => {
test('should set meta params for all instances of FieldFormats', () => {
fieldFormatRegisty.register([StringFormat]);

const ConcreteFormat = fieldFormatRegisty.getType(StringFormat.id);
const DecoratedStingFormat = fieldFormatRegisty.getType(StringFormat.id);

expect(ConcreteFormat).toBeDefined();
expect(DecoratedStingFormat).toBeDefined();

if (ConcreteFormat) {
const stringFormat = new ConcreteFormat({
if (DecoratedStingFormat) {
const stringFormat = new DecoratedStingFormat({
foo: 'foo',
});
const params = getValueOfPrivateField(stringFormat, '_params');
Expand All @@ -132,5 +133,39 @@ describe('FieldFormatRegisty', () => {
expect(params.parsedUrl).toHaveProperty('basePath');
}
});

test('should decorate static fields', () => {
fieldFormatRegisty.register([BoolFormat]);

const DecoratedBoolFormat = fieldFormatRegisty.getType(BoolFormat.id);

expect(DecoratedBoolFormat).toBeDefined();

if (DecoratedBoolFormat) {
expect(DecoratedBoolFormat.id).toBe(BoolFormat.id);
expect(DecoratedBoolFormat.fieldType).toBe(BoolFormat.fieldType);
}
});
});

describe('getByFieldType', () => {
test('should provide an public "getByFieldType" method', () => {
expect(fieldFormatRegisty.getByFieldType).toBeDefined();
expect(typeof fieldFormatRegisty.getByFieldType).toBe('function');
});

test('should decorate returns types', () => {
fieldFormatRegisty.register([StringFormat, BoolFormat]);

const [DecoratedStringFormat] = fieldFormatRegisty.getByFieldType(KBN_FIELD_TYPES.STRING);

expect(DecoratedStringFormat).toBeDefined();

const stingFormat = new DecoratedStringFormat({ foo: 'foo' });
const params = getValueOfPrivateField(stingFormat, '_params');

expect(params).toHaveProperty('foo');
expect(params).toHaveProperty('parsedUrl');
});
});
});
84 changes: 56 additions & 28 deletions src/plugins/data/public/field_formats_provider/field_formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

// eslint-disable-next-line max-classes-per-file
import { forOwn, isFunction, memoize } from 'lodash';
import { IUiSettingsClient, CoreSetup } from 'kibana/public';
import {
Expand All @@ -26,6 +27,7 @@ import {
IFieldFormatType,
IFieldFormatId,
FieldFormat,
IFieldFormatMetaParams,
} from '../../common';
import { FieldType } from './types';

Expand Down Expand Up @@ -75,14 +77,20 @@ export class FieldFormatRegisty {
* Get a derived FieldFormat class by its id.
*
* @param {IFieldFormatId} formatId - the format id
* @return {FieldFormat | void}
* @return {FieldFormat | undefined}
*/
getType = (formatId: IFieldFormatId): IFieldFormatType | void => {
const decoratedFieldFormat: any = this.fieldFormatMetaParamsDecorator(formatId);
getType = (formatId: IFieldFormatId): IFieldFormatType | undefined => {
const fieldFormat = this.fieldFormats.get(formatId);

if (decoratedFieldFormat) {
return decoratedFieldFormat as IFieldFormatType;
if (fieldFormat) {
const decoratedFieldFormat: any = this.fieldFormatMetaParamsDecorator(fieldFormat);

if (decoratedFieldFormat) {
return decoratedFieldFormat as IFieldFormatType;
}
}

return undefined;
};

/**
Expand All @@ -92,12 +100,12 @@ export class FieldFormatRegisty {
*
* @param {KBN_FIELD_TYPES} fieldType
* @param {ES_FIELD_TYPES[]} esTypes - Array of ES data types
* @return {FieldFormat | void}
* @return {FieldFormat | undefined}
*/
getDefaultType = (
fieldType: KBN_FIELD_TYPES,
esTypes: ES_FIELD_TYPES[]
): IFieldFormatType | void => {
): IFieldFormatType | undefined => {
const config = this.getDefaultConfig(fieldType, esTypes);

return this.getType(config.id);
Expand All @@ -108,11 +116,11 @@ export class FieldFormatRegisty {
* using the format:defaultTypeMap config map
*
* @param {ES_FIELD_TYPES[]} esTypes - Array of ES data types
* @return {ES_FIELD_TYPES | void}
* @return {ES_FIELD_TYPES | undefined}
*/
getTypeNameByEsTypes = (esTypes: ES_FIELD_TYPES[] | undefined): ES_FIELD_TYPES | void => {
getTypeNameByEsTypes = (esTypes: ES_FIELD_TYPES[] | undefined): ES_FIELD_TYPES | undefined => {
if (!Array.isArray(esTypes)) {
return;
return undefined;
}

return esTypes.find(type => this.defaultMap[type] && this.defaultMap[type].es);
Expand Down Expand Up @@ -196,9 +204,12 @@ export class FieldFormatRegisty {
* @return {FieldFormat[]}
*/
getByFieldType(fieldType: KBN_FIELD_TYPES): IFieldFormatType[] {
return [...this.fieldFormats.values()].filter(
(format: IFieldFormatType) => format.fieldType.indexOf(fieldType) !== -1
);
return [...this.fieldFormats.values()]
.filter((format: IFieldFormatType) => format && format.fieldType.indexOf(fieldType) !== -1)
.map(
(format: IFieldFormatType) =>
this.fieldFormatMetaParamsDecorator(format) as IFieldFormatType
);
}

/**
Expand Down Expand Up @@ -232,24 +243,41 @@ export class FieldFormatRegisty {
* FieldFormat decorator - provide a one way to add meta-params for all field formatters
*
* @private
* @param {IFieldFormatId} formatId - the format id
* @return {FieldFormat | void}
* @param {IFieldFormatType} fieldFormat - field format type
* @return {FieldFormat | undefined}
*/
private fieldFormatMetaParamsDecorator = (formatId: IFieldFormatId): Function | void => {
const concreteFieldFormat = this.fieldFormats.get(formatId);
const decorateMetaParams = (customOptions: Record<string, any> = {}) => ({
parsedUrl: {
origin: window.location.origin,
pathname: window.location.pathname,
basePath: this.basePath,
},
...customOptions,
});
private fieldFormatMetaParamsDecorator = (
fieldFormat: IFieldFormatType
): IFieldFormatType | undefined => {
const getMetaParams = (customParams: Record<string, any>) => this.buildMetaParams(customParams);

if (concreteFieldFormat) {
return function(params: Record<string, any> = {}, getConfig?: Function) {
return new concreteFieldFormat(decorateMetaParams(params), getConfig);
if (fieldFormat) {
return class DecoratedFieldFormat extends fieldFormat {
static id = fieldFormat.id;
static fieldType = fieldFormat.fieldType;

constructor(params: Record<string, any> = {}, getConfig?: Function) {
super(getMetaParams(params), getConfig);
}
};
}

return undefined;
};

/**
* Build Meta Params
*
* @static
* @param {Record<string, any>} custom params
* @return {Record<string, any>}
*/
private buildMetaParams = <T extends IFieldFormatMetaParams>(customParams: T): T => ({
parsedUrl: {
origin: window.location.origin,
pathname: window.location.pathname,
basePath: this.basePath,
},
...customParams,
});
}

0 comments on commit 2c6ed6d

Please sign in to comment.