Skip to content

Commit

Permalink
[FieldFormats] Lazy load field formats editors (elastic#106439)
Browse files Browse the repository at this point in the history
Dosant authored and kibanamachine committed Jul 28, 2021
1 parent 9c72424 commit e9ec695
Showing 51 changed files with 541 additions and 177 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -6,11 +6,12 @@
* Side Public License, v 1.
*/

import { NumberFormatEditor } from '../number';
import { NumberFormatEditor } from '../number/number';
import { defaultState } from '../default';
import { formatId } from './constants';

export class BytesFormatEditor extends NumberFormatEditor {
static formatId = 'bytes';
static formatId = formatId;
state = {
...defaultState,
sampleInputs: [256, 1024, 5150000, 1990000000],
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'bytes';
Original file line number Diff line number Diff line change
@@ -5,5 +5,10 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { formatId } from './constants';
import { FieldFormatEditorFactory } from '../types';

export { BytesFormatEditor } from './bytes';
export type { BytesFormatEditor } from './bytes';
export const bytesFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./bytes').then((m) => m.BytesFormatEditor);
bytesFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -12,9 +12,11 @@ import { EuiBasicTable, EuiButton, EuiColorPicker, EuiFieldText, EuiSpacer } fro

import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { DefaultFormatEditor, FormatEditorProps } from '../default';
import { DefaultFormatEditor } from '../default/default';
import { formatId } from './constants';

import { fieldFormats } from '../../../../../../data/public';
import { FormatEditorProps } from '../types';

interface Color {
range?: string;
@@ -32,7 +34,7 @@ interface ColorFormatEditorFormatParams {
}

export class ColorFormatEditor extends DefaultFormatEditor<ColorFormatEditorFormatParams> {
static formatId = 'color';
static formatId = formatId;
constructor(props: FormatEditorProps<ColorFormatEditorFormatParams>) {
super(props);
this.onChange({
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'color';
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { ColorFormatEditor } from './color';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { ColorFormatEditor } from './color';
export const colorFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./color').then((m) => m.ColorFormatEditor);
colorFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'date';
Original file line number Diff line number Diff line change
@@ -12,7 +12,8 @@ import moment from 'moment';
import { EuiCode, EuiFieldText, EuiFormRow, EuiIcon, EuiLink } from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { DefaultFormatEditor, defaultState } from '../default';
import { DefaultFormatEditor, defaultState } from '../default/default';
import { formatId } from './constants';

import { FormatEditorSamples } from '../../samples';

@@ -21,7 +22,7 @@ interface DateFormatEditorFormatParams {
}

export class DateFormatEditor extends DefaultFormatEditor<DateFormatEditorFormatParams> {
static formatId = 'date';
static formatId = formatId;
state = {
...defaultState,
sampleInputs: [
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { DateFormatEditor } from './date';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { DateFormatEditor } from './date';
export const dateFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./date').then((m) => m.DateFormatEditor);
dateFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'date_nanos';
Original file line number Diff line number Diff line change
@@ -11,7 +11,8 @@ import React, { Fragment } from 'react';
import { EuiCode, EuiFieldText, EuiFormRow, EuiIcon, EuiLink } from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { DefaultFormatEditor, defaultState } from '../default';
import { DefaultFormatEditor, defaultState } from '../default/default';
import { formatId } from './constants';

import { FormatEditorSamples } from '../../samples';

@@ -20,7 +21,7 @@ interface DateNanosFormatEditorFormatParams {
}

export class DateNanosFormatEditor extends DefaultFormatEditor<DateNanosFormatEditorFormatParams> {
static formatId = 'date_nanos';
static formatId = formatId;
state = {
...defaultState,
sampleInputs: [
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { DateNanosFormatEditor } from './date_nanos';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { DateNanosFormatEditor } from './date_nanos';
export const dateNanosFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./date_nanos').then((m) => m.DateNanosFormatEditor);
dateNanosFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'default';
Original file line number Diff line number Diff line change
@@ -9,9 +9,10 @@
import React, { PureComponent, ReactText } from 'react';
import { i18n } from '@kbn/i18n';

import { FieldFormat, FieldFormatsContentType } from 'src/plugins/data/public';
import { FieldFormatsContentType } from 'src/plugins/data/public';
import { Sample, SampleInput } from '../../types';
import { FormatSelectEditorProps } from '../../field_format_editor';
import { FormatEditorProps } from '../types';
import { formatId } from './constants';

export const convertSampleInput = (
converter: (input: SampleInput) => string,
@@ -44,14 +45,6 @@ interface SampleInputs {
[key: string]: Array<ReactText[] | ReactText>;
}

export interface FormatEditorProps<P> {
fieldType: string;
format: FieldFormat;
formatParams: { type?: string } & P;
onChange: (newParams: Record<string, any>) => void;
onError: FormatSelectEditorProps['onError'];
}

export interface FormatEditorState {
sampleInputs: SampleInput[];
sampleConverterType: FieldFormatsContentType;
@@ -72,7 +65,7 @@ export class DefaultFormatEditor<P = {}, S = {}> extends PureComponent<
FormatEditorProps<P>,
FormatEditorState & S
> {
static formatId = 'default';
static formatId = formatId;
state = defaultState as FormatEditorState & S;

static getDerivedStateFromProps(nextProps: FormatEditorProps<{}>, state: FormatEditorState) {
Original file line number Diff line number Diff line change
@@ -6,4 +6,13 @@
* Side Public License, v 1.
*/

export { DefaultFormatEditor, defaultState, FormatEditorProps, FormatEditorState } from './default';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export { defaultState, FormatEditorState } from './default';
export type { FormatEditorProps } from '../types';
export type { DefaultFormatEditor } from './default';

export const defaultFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./default').then((m) => m.DefaultFormatEditor);
defaultFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'duration';
Original file line number Diff line number Diff line change
@@ -13,14 +13,11 @@ import { EuiFieldNumber, EuiFormRow, EuiSelect, EuiSwitch } from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import {
DefaultFormatEditor,
defaultState,
FormatEditorProps,
FormatEditorState,
} from '../default';
import { DefaultFormatEditor, defaultState, FormatEditorState } from '../default/default';

import { FormatEditorSamples } from '../../samples';
import { formatId } from './constants';
import { FormatEditorProps } from '../types';

interface DurationFormatEditorState {
hasDecimalError: boolean;
@@ -49,7 +46,7 @@ export class DurationFormatEditor extends DefaultFormatEditor<
DurationFormatEditorFormatParams,
DurationFormatEditorState
> {
static formatId = 'duration';
static formatId = formatId;
state = {
...defaultState,
sampleInputs: [-123, 1, 12, 123, 658, 1988, 3857, 123292, 923528271],
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { DurationFormatEditor } from './duration';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { DurationFormatEditor } from './duration';
export const durationFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./duration').then((m) => m.DurationFormatEditor);
durationFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'histogram';
Original file line number Diff line number Diff line change
@@ -10,16 +10,17 @@ import React, { Fragment } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiSelect, EuiFieldText, EuiFormRow, EuiIcon, EuiLink } from '@elastic/eui';
import { DefaultFormatEditor, defaultState } from '../default';
import { DefaultFormatEditor, defaultState } from '../default/default';
import { FormatEditorSamples } from '../../samples';
import { formatId } from './constants';

export interface HistogramFormatEditorParams {
id: 'bytes' | 'percent' | 'number';
params: { pattern?: string } & Record<string, unknown>;
}

export class HistogramFormatEditor extends DefaultFormatEditor<HistogramFormatEditorParams> {
static formatId = 'histogram';
static formatId = formatId;
state = {
...defaultState,
sampleInputs: [
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { HistogramFormatEditor } from './histogram';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { HistogramFormatEditor } from './histogram';
export const histogramFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./histogram').then((m) => m.HistogramFormatEditor);
histogramFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -6,17 +6,19 @@
* Side Public License, v 1.
*/

export { DefaultFormatEditor } from './default';
export type { FieldFormatEditor, FieldFormatEditorFactory, FormatEditorProps } from './types';

export { BytesFormatEditor } from './bytes';
export { ColorFormatEditor } from './color';
export { DateFormatEditor } from './date';
export { DateNanosFormatEditor } from './date_nanos';
export { DurationFormatEditor } from './duration';
export { NumberFormatEditor } from './number';
export { PercentFormatEditor } from './percent';
export { StaticLookupFormatEditor } from './static_lookup';
export { StringFormatEditor } from './string';
export { TruncateFormatEditor } from './truncate';
export { UrlFormatEditor } from './url';
export { HistogramFormatEditor } from './histogram';
export { DefaultFormatEditor, defaultFormatEditorFactory } from './default';

export { BytesFormatEditor, bytesFormatEditorFactory } from './bytes';
export { ColorFormatEditor, colorFormatEditorFactory } from './color';
export { DateFormatEditor, dateFormatEditorFactory } from './date';
export { DateNanosFormatEditor, dateNanosFormatEditorFactory } from './date_nanos';
export { DurationFormatEditor, durationFormatEditorFactory } from './duration';
export { NumberFormatEditor, numberFormatEditorFactory } from './number';
export { PercentFormatEditor, percentFormatEditorFactory } from './percent';
export { StaticLookupFormatEditor, staticLookupFormatEditorFactory } from './static_lookup';
export { StringFormatEditor, stringFormatEditorFactory } from './string';
export { TruncateFormatEditor, truncateFormatEditorFactory } from './truncate';
export { UrlFormatEditor, urlFormatEditorFactory } from './url';
export { HistogramFormatEditor, histogramFormatEditorFactory } from './histogram';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'number';
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { NumberFormatEditor } from './number';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { NumberFormatEditor } from './number';
export const numberFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./number').then((m) => m.NumberFormatEditor);
numberFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -11,9 +11,10 @@ import React, { Fragment } from 'react';
import { EuiCode, EuiFieldText, EuiFormRow, EuiIcon, EuiLink } from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { DefaultFormatEditor, defaultState } from '../default';
import { DefaultFormatEditor, defaultState } from '../default/default';

import { FormatEditorSamples } from '../../samples';
import { formatId } from './constants';

import { context as contextType } from '../../../../../../kibana_react/public';

@@ -23,7 +24,7 @@ export interface NumberFormatEditorParams {

export class NumberFormatEditor extends DefaultFormatEditor<NumberFormatEditorParams> {
static contextType = contextType;
static formatId = 'number';
static formatId = formatId;

context!: React.ContextType<typeof contextType>;
state = {
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'percent';
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { PercentFormatEditor } from './percent';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { PercentFormatEditor } from './percent';
export const percentFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./percent').then((m) => m.PercentFormatEditor);
percentFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -6,11 +6,12 @@
* Side Public License, v 1.
*/

import { NumberFormatEditor } from '../number';
import { NumberFormatEditor } from '../number/number';
import { defaultState } from '../default';
import { formatId } from './constants';

export class PercentFormatEditor extends NumberFormatEditor {
static formatId = 'percent';
static formatId = formatId;
state = {
...defaultState,
sampleInputs: [0.1, 0.99999, 1, 100, 1000],
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'static_lookup';
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { StaticLookupFormatEditor } from './static_lookup';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { StaticLookupFormatEditor } from './static_lookup';
export const staticLookupFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./static_lookup').then((m) => m.StaticLookupFormatEditor);
staticLookupFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -12,7 +12,8 @@ import { EuiBasicTable, EuiButton, EuiFieldText, EuiFormRow, EuiSpacer } from '@

import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { DefaultFormatEditor } from '../default';
import { DefaultFormatEditor } from '../default/default';
import { formatId } from './constants';

export interface StaticLookupFormatEditorFormatParams {
lookupEntries: Array<{ key: string; value: string }>;
@@ -26,7 +27,7 @@ interface StaticLookupItem {
}

export class StaticLookupFormatEditor extends DefaultFormatEditor<StaticLookupFormatEditorFormatParams> {
static formatId = 'static_lookup';
static formatId = formatId;
onLookupChange = (newLookupParams: { value?: string; key?: string }, index: number) => {
const lookupEntries = [...this.props.formatParams.lookupEntries];
lookupEntries[index] = {
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'string';
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { StringFormatEditor } from './string';
import { FieldFormatEditorFactory } from '../types';
import { formatId } from './constants';

export type { StringFormatEditor } from './string';
export const stringFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./string').then((m) => m.StringFormatEditor);
stringFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -11,9 +11,10 @@ import React, { Fragment } from 'react';
import { EuiFormRow, EuiSelect } from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { DefaultFormatEditor, defaultState } from '../default';
import { DefaultFormatEditor, defaultState } from '../default/default';

import { FormatEditorSamples } from '../../samples';
import { formatId } from './constants';

interface StringFormatEditorFormatParams {
transform: string;
@@ -25,7 +26,7 @@ interface TransformOptions {
}

export class StringFormatEditor extends DefaultFormatEditor<StringFormatEditorFormatParams> {
static formatId = 'string';
static formatId = formatId;
state = {
...defaultState,
sampleInputs: [
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'truncate';
Original file line number Diff line number Diff line change
@@ -6,4 +6,10 @@
* Side Public License, v 1.
*/

export { TruncateFormatEditor } from './truncate';
import { formatId } from './constants';
import { FieldFormatEditorFactory } from '../types';

export type { TruncateFormatEditor } from './truncate';
export const truncateFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./truncate').then((m) => m.TruncateFormatEditor);
truncateFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -11,18 +11,19 @@ import React, { Fragment } from 'react';
import { EuiFieldNumber, EuiFormRow } from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { DefaultFormatEditor, defaultState } from '../default';
import { DefaultFormatEditor, defaultState } from '../default/default';

import { FormatEditorSamples } from '../../samples';

import { sample } from './sample';
import { formatId } from './constants';

interface TruncateFormatEditorFormatParams {
fieldLength: number;
}

export class TruncateFormatEditor extends DefaultFormatEditor<TruncateFormatEditorFormatParams> {
static formatId = 'truncate';
static formatId = formatId;
state = {
...defaultState,
sampleInputs: [sample],
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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 type { ComponentType } from 'react';
import type { FieldFormat } from '../../../../../data/common';
import type { FormatSelectEditorProps } from '../field_format_editor';

/**
* Props for received by {@link FieldFormatEditor}
* @public
*/
export interface FormatEditorProps<P> {
fieldType: string;
format: FieldFormat;
formatParams: { type?: string } & P;
onChange: (newParams: { [key: string]: any }) => void;
onError: FormatSelectEditorProps['onError'];
}

/**
* A React component for editing custom field format params
* @public
*/
export type FieldFormatEditor<FormatParams = {}> = ComponentType<
FormatEditorProps<FormatParams>
> & { formatId: string };

/**
* A factory for registering field format editor for a field format with `formatId`
* @public
*/
export type FieldFormatEditorFactory<FormatParams = any> = (() => Promise<
FieldFormatEditor<FormatParams>
>) & {
formatId: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export const formatId = 'url';
Original file line number Diff line number Diff line change
@@ -5,5 +5,11 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { formatId } from './constants';
import { FieldFormatEditorFactory } from '../types';

export { UrlFormatEditor } from './url';
export type { UrlFormatEditor } from './url';

export const urlFormatEditorFactory: FieldFormatEditorFactory = () =>
import('./url').then((m) => m.UrlFormatEditor);
urlFormatEditorFactory.formatId = formatId;
Original file line number Diff line number Diff line change
@@ -18,11 +18,13 @@ import {
} from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { DefaultFormatEditor, FormatEditorProps } from '../default';
import { DefaultFormatEditor } from '../default/default';

import { FormatEditorSamples } from '../../samples';
import { formatId } from './constants';

import { context as contextType } from '../../../../../../kibana_react/public';
import { FormatEditorProps } from '../types';

interface OnChangeParam {
type: string;
@@ -54,7 +56,7 @@ export class UrlFormatEditor extends DefaultFormatEditor<
UrlFormatEditorFormatState
> {
static contextType = contextType;
static formatId = 'url';
static formatId = formatId;
private get sampleIconPath() {
const sampleIconPath = `/plugins/indexPatternManagement/assets/icons/{{value}}.png`;
return this.context?.services.http
Original file line number Diff line number Diff line change
@@ -101,7 +101,7 @@ export class FormatSelectEditor extends PureComponent<
: undefined
);

onFormatParamsChange = (newParams: { fieldType: string; [key: string]: any }) => {
onFormatParamsChange = (newParams: { [key: string]: any }) => {
const { fieldFormatId } = this.state;
this.onFormatChange(fieldFormatId as string, newParams);
};
Original file line number Diff line number Diff line change
@@ -6,43 +6,46 @@
* Side Public License, v 1.
*/

import React, { PureComponent, Fragment } from 'react';
import { FieldFormat } from 'src/plugins/data/public';
import { EuiDelayRender, EuiLoadingContent } from '@elastic/eui';
import { memoize } from 'lodash';
import React, { PureComponent, LazyExoticComponent } from 'react';
import type { FieldFormat } from 'src/plugins/data/public';
import { FieldFormatEditorFactory, FieldFormatEditor } from './editors';

export interface FormatEditorProps {
fieldType: string;
fieldFormat: FieldFormat;
fieldFormatId: string;
fieldFormatParams: { [key: string]: unknown };
fieldFormatEditors: any;
onChange: (change: { fieldType: string; [key: string]: any }) => void;
onChange: (change: { [key: string]: any }) => void;
onError: (error?: string) => void;
}

interface EditorComponentProps {
fieldType: FormatEditorProps['fieldType'];
format: FormatEditorProps['fieldFormat'];
formatParams: FormatEditorProps['fieldFormatParams'];
onChange: FormatEditorProps['onChange'];
onError: FormatEditorProps['onError'];
}

interface FormatEditorState {
EditorComponent: React.FC<EditorComponentProps>;
EditorComponent: LazyExoticComponent<FieldFormatEditor> | null;
fieldFormatId?: string;
}

// use memoize to get stable reference
const unwrapEditor = memoize(
(editorFactory: FieldFormatEditorFactory | null): FormatEditorState['EditorComponent'] => {
if (!editorFactory) return null;
return React.lazy(() => editorFactory().then((editor) => ({ default: editor })));
}
);

export class FormatEditor extends PureComponent<FormatEditorProps, FormatEditorState> {
constructor(props: FormatEditorProps) {
super(props);
this.state = {
EditorComponent: props.fieldFormatEditors.getById(props.fieldFormatId),
EditorComponent: unwrapEditor(props.fieldFormatEditors.getById(props.fieldFormatId)),
};
}

static getDerivedStateFromProps(nextProps: FormatEditorProps) {
return {
EditorComponent: nextProps.fieldFormatEditors.getById(nextProps.fieldFormatId) || null,
EditorComponent: unwrapEditor(nextProps.fieldFormatEditors.getById(nextProps.fieldFormatId)),
};
}

@@ -51,17 +54,29 @@ export class FormatEditor extends PureComponent<FormatEditorProps, FormatEditorS
const { fieldType, fieldFormat, fieldFormatParams, onChange, onError } = this.props;

return (
<Fragment>
<>
{EditorComponent ? (
<EditorComponent
fieldType={fieldType}
format={fieldFormat}
formatParams={fieldFormatParams}
onChange={onChange}
onError={onError}
/>
<React.Suspense
fallback={
// We specify minHeight to avoid too mitigate layout shifts while loading an editor
// ~430 corresponds to "4 lines" of EuiLoadingContent
<div style={{ minHeight: 430, marginTop: 8 }}>
<EuiDelayRender>
<EuiLoadingContent lines={4} />
</EuiDelayRender>
</div>
}
>
<EditorComponent
fieldType={fieldType}
format={fieldFormat}
formatParams={fieldFormatParams}
onChange={onChange}
onError={onError}
/>
</React.Suspense>
) : null}
</Fragment>
</>
);
}
}
1 change: 1 addition & 0 deletions src/plugins/index_pattern_field_editor/public/index.ts
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ import { IndexPatternFieldEditorPlugin } from './plugin';

export { PluginStart as IndexPatternFieldEditorStart } from './types';
export { DefaultFormatEditor } from './components';
export { FieldFormatEditorFactory, FieldFormatEditor, FormatEditorProps } from './components';

export function plugin() {
return new IndexPatternFieldEditorPlugin();
Original file line number Diff line number Diff line change
@@ -6,16 +6,16 @@
* Side Public License, v 1.
*/

import { DefaultFormatEditor } from '../../components/field_format_editor';
import { FieldFormatEditorFactory } from '../../components/field_format_editor';

export class FieldFormatEditors {
private editors: Array<typeof DefaultFormatEditor> = [];
private editors: FieldFormatEditorFactory[] = [];

public setup(defaultFieldEditors: FieldFormatEditors['editors'] = []) {
public setup(defaultFieldEditors: FieldFormatEditorFactory[] = []) {
this.editors = defaultFieldEditors;

return {
register: (editor: typeof DefaultFormatEditor) => {
register: (editor: FieldFormatEditorFactory) => {
this.editors.push(editor);
},
};
Original file line number Diff line number Diff line change
@@ -9,18 +9,19 @@
import { FieldFormatEditors } from './field_format_editors';

import {
BytesFormatEditor,
ColorFormatEditor,
DateFormatEditor,
DateNanosFormatEditor,
DurationFormatEditor,
NumberFormatEditor,
PercentFormatEditor,
StaticLookupFormatEditor,
StringFormatEditor,
TruncateFormatEditor,
UrlFormatEditor,
HistogramFormatEditor,
bytesFormatEditorFactory,
colorFormatEditorFactory,
dateFormatEditorFactory,
dateNanosFormatEditorFactory,
durationFormatEditorFactory,
numberFormatEditorFactory,
percentFormatEditorFactory,
staticLookupFormatEditorFactory,
stringFormatEditorFactory,
truncateFormatEditorFactory,
urlFormatEditorFactory,
histogramFormatEditorFactory,
FieldFormatEditorFactory,
} from '../components';

/**
@@ -36,22 +37,24 @@ export class FormatEditorService {
}

public setup() {
const defaultFieldFormatEditors = [
BytesFormatEditor,
ColorFormatEditor,
DateFormatEditor,
DateNanosFormatEditor,
DurationFormatEditor,
NumberFormatEditor,
PercentFormatEditor,
StaticLookupFormatEditor,
StringFormatEditor,
TruncateFormatEditor,
UrlFormatEditor,
HistogramFormatEditor,
const defaultFieldFormatEditorFactories: FieldFormatEditorFactory[] = [
bytesFormatEditorFactory,
colorFormatEditorFactory,
dateFormatEditorFactory,
dateNanosFormatEditorFactory,
durationFormatEditorFactory,
numberFormatEditorFactory,
percentFormatEditorFactory,
staticLookupFormatEditorFactory,
stringFormatEditorFactory,
truncateFormatEditorFactory,
urlFormatEditorFactory,
histogramFormatEditorFactory,
];

const fieldFormatEditorsSetup = this.fieldFormatEditors.setup(defaultFieldFormatEditors);
const fieldFormatEditorsSetup = this.fieldFormatEditors.setup(
defaultFieldFormatEditorFactories
);

return {
fieldFormatEditors: fieldFormatEditorsSetup,

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ import React, { PureComponent } from 'react';
import { shallow } from 'enzyme';

import { FieldFormatEditor } from './field_format_editor';
import type { DefaultFormatEditor } from 'src/plugins/index_pattern_field_editor/public';
import type { FieldFormat } from '../../../../../../data/public';

class TestEditor extends PureComponent {
render() {
@@ -26,15 +26,15 @@ const formatEditors = {
ip: TestEditor,
number: TestEditor,
},
getById: jest.fn(() => TestEditor),
getById: jest.fn(() => () => Promise.resolve(TestEditor)),
};

describe('FieldFormatEditor', () => {
it('should render normally', async () => {
const component = shallow(
<FieldFormatEditor
fieldType="number"
fieldFormat={{} as DefaultFormatEditor}
fieldFormat={{} as FieldFormat}
fieldFormatId="number"
fieldFormatParams={{}}
fieldFormatEditors={formatEditors}
@@ -50,7 +50,7 @@ describe('FieldFormatEditor', () => {
const component = shallow(
<FieldFormatEditor
fieldType="number"
fieldFormat={{} as DefaultFormatEditor}
fieldFormat={{} as FieldFormat}
fieldFormatId="ip"
fieldFormatParams={{}}
fieldFormatEditors={formatEditors}
Original file line number Diff line number Diff line change
@@ -6,45 +6,51 @@
* Side Public License, v 1.
*/

import React, { PureComponent, Fragment } from 'react';
import type { DefaultFormatEditor } from 'src/plugins/index_pattern_field_editor/public';
import React, { LazyExoticComponent, PureComponent } from 'react';
import { memoize } from 'lodash';
import { EuiDelayRender, EuiLoadingContent } from '@elastic/eui';
import type {
FieldFormatEditorFactory,
FieldFormatEditor as InnerFieldFormatEditor,
} from 'src/plugins/index_pattern_field_editor/public';
import type { FieldFormat } from 'src/plugins/data/public';

export interface FieldFormatEditorProps {
fieldType: string;
fieldFormat: DefaultFormatEditor;
fieldFormat: FieldFormat;
fieldFormatId: string;
fieldFormatParams: { [key: string]: unknown };
fieldFormatEditors: any;
onChange: (change: { fieldType: string; [key: string]: any }) => void;
onChange: (change: { [key: string]: any }) => void;
onError: (error?: string) => void;
}

interface EditorComponentProps {
fieldType: FieldFormatEditorProps['fieldType'];
format: FieldFormatEditorProps['fieldFormat'];
formatParams: FieldFormatEditorProps['fieldFormatParams'];
onChange: FieldFormatEditorProps['onChange'];
onError: FieldFormatEditorProps['onError'];
}

interface FieldFormatEditorState {
EditorComponent: React.FC<EditorComponentProps>;
EditorComponent: LazyExoticComponent<InnerFieldFormatEditor> | null;
}

// use memoize to get stable reference
const unwrapEditor = memoize(
(editorFactory: FieldFormatEditorFactory | null): FieldFormatEditorState['EditorComponent'] => {
if (!editorFactory) return null;
return React.lazy(() => editorFactory().then((editor) => ({ default: editor })));
}
);

export class FieldFormatEditor extends PureComponent<
FieldFormatEditorProps,
FieldFormatEditorState
> {
constructor(props: FieldFormatEditorProps) {
super(props);
this.state = {
EditorComponent: props.fieldFormatEditors.getById(props.fieldFormatId),
EditorComponent: unwrapEditor(props.fieldFormatEditors.getById(props.fieldFormatId)),
};
}

static getDerivedStateFromProps(nextProps: FieldFormatEditorProps) {
return {
EditorComponent: nextProps.fieldFormatEditors.getById(nextProps.fieldFormatId) || null,
EditorComponent: unwrapEditor(nextProps.fieldFormatEditors.getById(nextProps.fieldFormatId)),
};
}

@@ -53,17 +59,29 @@ export class FieldFormatEditor extends PureComponent<
const { fieldType, fieldFormat, fieldFormatParams, onChange, onError } = this.props;

return (
<Fragment>
<>
{EditorComponent ? (
<EditorComponent
fieldType={fieldType}
format={fieldFormat}
formatParams={fieldFormatParams}
onChange={onChange}
onError={onError}
/>
<React.Suspense
fallback={
// We specify minHeight to avoid too mitigate layout shifts while loading an editor
// ~430 corresponds to "4 lines" of EuiLoadingContent
<div style={{ minHeight: 430, marginTop: 8 }}>
<EuiDelayRender>
<EuiLoadingContent lines={4} />
</EuiDelayRender>
</div>
}
>
<EditorComponent
fieldType={fieldType}
format={fieldFormat}
formatParams={fieldFormatParams}
onChange={onChange}
onError={onError}
/>
</React.Suspense>
) : null}
</Fragment>
</>
);
}
}
Original file line number Diff line number Diff line change
@@ -253,7 +253,7 @@ export class FieldEditor extends PureComponent<FieldEdiorProps, FieldEditorState
});
};

onFormatParamsChange = (newParams: { fieldType: string; [key: string]: any }) => {
onFormatParamsChange = (newParams: { [key: string]: any }) => {
const { fieldFormatId } = this.state;
this.onFormatChange(fieldFormatId as string, newParams);
};

0 comments on commit e9ec695

Please sign in to comment.