diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/__snapshots__/format_editor.test.tsx.snap b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/__snapshots__/format_editor.test.tsx.snap index 82d21eb5d30ad..6dff1359de9a7 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/__snapshots__/format_editor.test.tsx.snap +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/__snapshots__/format_editor.test.tsx.snap @@ -2,24 +2,66 @@ exports[`FieldFormatEditor should render normally 1`] = ` - + + + + + + } + > + + `; exports[`FieldFormatEditor should render nothing if there is no editor for the format 1`] = ` - + + + + + + } + > + + `; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/bytes.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/bytes.ts index 8afcba38e5f40..434ec5d09bf51 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/bytes.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/bytes.ts @@ -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], diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/constants.ts new file mode 100644 index 0000000000000..f057551fa35ba --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/index.ts index 81356e02c9ab2..5d631e22a8890 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/color.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/color.tsx index 1e899a7179554..3570ef4c9d33a 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/color.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/color.tsx @@ -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 { - static formatId = 'color'; + static formatId = formatId; constructor(props: FormatEditorProps) { super(props); this.onChange({ diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/constants.ts new file mode 100644 index 0000000000000..ab19c423b61d9 --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/index.ts index 0a2960ae3dfbb..b6cadb8aae43b 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/color/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/constants.ts new file mode 100644 index 0000000000000..714ca3e619d72 --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/date.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/date.tsx index 62fb08855ce93..455d3bf181135 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/date.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/date.tsx @@ -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 { - static formatId = 'date'; + static formatId = formatId; state = { ...defaultState, sampleInputs: [ diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/index.ts index 9db645b3f21a3..9fb47b285f669 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/constants.ts new file mode 100644 index 0000000000000..17c316140bf0f --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/date_nanos.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/date_nanos.tsx index d9ee099aaef36..9e18b75521b01 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/date_nanos.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/date_nanos.tsx @@ -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 { - static formatId = 'date_nanos'; + static formatId = formatId; state = { ...defaultState, sampleInputs: [ diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/index.ts index 9aab1bb9dc223..ade21b27f60ef 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/date_nanos/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/constants.ts new file mode 100644 index 0000000000000..1f65639359114 --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/default.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/default.tsx index a282faaa4d2b5..7228a02afa2a5 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/default.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/default.tsx @@ -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; } -export interface FormatEditorProps

{ - fieldType: string; - format: FieldFormat; - formatParams: { type?: string } & P; - onChange: (newParams: Record) => void; - onError: FormatSelectEditorProps['onError']; -} - export interface FormatEditorState { sampleInputs: SampleInput[]; sampleConverterType: FieldFormatsContentType; @@ -72,7 +65,7 @@ export class DefaultFormatEditor

extends PureComponent< FormatEditorProps

, FormatEditorState & S > { - static formatId = 'default'; + static formatId = formatId; state = defaultState as FormatEditorState & S; static getDerivedStateFromProps(nextProps: FormatEditorProps<{}>, state: FormatEditorState) { diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/index.ts index 1636c3f4a83cd..31d7e95897090 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/default/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/constants.ts new file mode 100644 index 0000000000000..ab146dc30e551 --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/duration.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/duration.tsx index d61d14aac3fc7..2bfb0182cbb88 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/duration.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/duration.tsx @@ -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], diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/index.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/index.tsx index cf3d7b85147de..8e489fbb2a464 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/index.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/duration/index.tsx @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/constants.ts new file mode 100644 index 0000000000000..a772129a1d276 --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/histogram.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/histogram.tsx index 0f13439e1269b..ce5b72b11559c 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/histogram.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/histogram.tsx @@ -10,8 +10,9 @@ 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'; @@ -19,7 +20,7 @@ export interface HistogramFormatEditorParams { } export class HistogramFormatEditor extends DefaultFormatEditor { - static formatId = 'histogram'; + static formatId = formatId; state = { ...defaultState, sampleInputs: [ diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/index.ts index 221895f4cba23..071581893f9d9 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/histogram/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/index.ts index 41d60c6e2144f..fceb3511301c0 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/index.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/constants.ts new file mode 100644 index 0000000000000..bb58521754d4f --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/index.ts index 0a3554feb02bc..7589c7b89c01b 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/number.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/number.tsx index f55c0c5f06c12..83110a4e42574 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/number.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/number.tsx @@ -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 { static contextType = contextType; - static formatId = 'number'; + static formatId = formatId; context!: React.ContextType; state = { diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/constants.ts new file mode 100644 index 0000000000000..282a02d41ffb8 --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/index.ts index 3336445035ac8..5fd8871f2798b 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/percent.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/percent.tsx index c7d4814f57c23..986217793c1d4 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/percent.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/percent.tsx @@ -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], diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/constants.ts new file mode 100644 index 0000000000000..e6a9168ab8aed --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/index.ts index 85020368ff813..325e132e9d791 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/static_lookup.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/static_lookup.tsx index 8ac03bb23bd25..485660fbb2bd4 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/static_lookup.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/static_lookup/static_lookup.tsx @@ -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 { - static formatId = 'static_lookup'; + static formatId = formatId; onLookupChange = (newLookupParams: { value?: string; key?: string }, index: number) => { const lookupEntries = [...this.props.formatParams.lookupEntries]; lookupEntries[index] = { diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/constants.ts new file mode 100644 index 0000000000000..4c4f9a5c3fc5d --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/index.ts index 6a44f8c0f821b..194b2444c5576 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/string.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/string.tsx index e86a62775cebc..c5d53a0ce9c95 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/string.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/string/string.tsx @@ -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 { - static formatId = 'string'; + static formatId = formatId; state = { ...defaultState, sampleInputs: [ diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/constants.ts new file mode 100644 index 0000000000000..01e8e4593c1c6 --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/index.ts index f41f62a0d3371..2b0cfda4dcab3 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/truncate.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/truncate.tsx index 03b7d6e0573cc..8d4a227270718 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/truncate.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/truncate/truncate.tsx @@ -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 { - static formatId = 'truncate'; + static formatId = formatId; state = { ...defaultState, sampleInputs: [sample], diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/types.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/types.ts new file mode 100644 index 0000000000000..556078286e524 --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/types.ts @@ -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

{ + 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 = ComponentType< + FormatEditorProps +> & { formatId: string }; + +/** + * A factory for registering field format editor for a field format with `formatId` + * @public + */ +export type FieldFormatEditorFactory = (() => Promise< + FieldFormatEditor +>) & { + formatId: string; +}; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/constants.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/constants.ts new file mode 100644 index 0000000000000..ab6c5bc34f31a --- /dev/null +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/constants.ts @@ -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'; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/index.ts b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/index.ts index 9bf60ddcbddbd..6da051003554c 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/index.ts +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/index.ts @@ -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; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/url.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/url.tsx index 3b00deef19e01..b5627a16732d8 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/url.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/url/url.tsx @@ -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 diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/field_format_editor.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/field_format_editor.tsx index 155fbc7fd31f5..ccb6cf7794f87 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/field_format_editor.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/field_format_editor.tsx @@ -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); }; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/format_editor.tsx b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/format_editor.tsx index 043a911e69812..dbbaf51f114b1 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/format_editor.tsx +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/format_editor.tsx @@ -6,8 +6,11 @@ * 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; @@ -15,34 +18,34 @@ export interface FormatEditorProps { 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; + EditorComponent: LazyExoticComponent | 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 { 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 + <> {EditorComponent ? ( - + + + + + + } + > + + ) : null} - + ); } } diff --git a/src/plugins/index_pattern_field_editor/public/index.ts b/src/plugins/index_pattern_field_editor/public/index.ts index f89490735973b..a63c9ada52e3d 100644 --- a/src/plugins/index_pattern_field_editor/public/index.ts +++ b/src/plugins/index_pattern_field_editor/public/index.ts @@ -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(); diff --git a/src/plugins/index_pattern_field_editor/public/service/field_format_editors/field_format_editors.ts b/src/plugins/index_pattern_field_editor/public/service/field_format_editors/field_format_editors.ts index fdc54a39c8c2a..8e3b4691b9d91 100644 --- a/src/plugins/index_pattern_field_editor/public/service/field_format_editors/field_format_editors.ts +++ b/src/plugins/index_pattern_field_editor/public/service/field_format_editors/field_format_editors.ts @@ -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 = []; + 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); }, }; diff --git a/src/plugins/index_pattern_field_editor/public/service/format_editor_service.ts b/src/plugins/index_pattern_field_editor/public/service/format_editor_service.ts index faabc7f5b9450..69ae89a42c947 100644 --- a/src/plugins/index_pattern_field_editor/public/service/format_editor_service.ts +++ b/src/plugins/index_pattern_field_editor/public/service/format_editor_service.ts @@ -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, diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap index 82d21eb5d30ad..6dff1359de9a7 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/__snapshots__/field_format_editor.test.tsx.snap @@ -2,24 +2,66 @@ exports[`FieldFormatEditor should render normally 1`] = ` - + + + + + + } + > + + `; exports[`FieldFormatEditor should render nothing if there is no editor for the format 1`] = ` - + + + + + + } + > + + `; diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.test.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.test.tsx index 78dc87f7a8027..c2f0c7cbfd64c 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.test.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/field_format_editor.test.tsx @@ -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,7 +26,7 @@ const formatEditors = { ip: TestEditor, number: TestEditor, }, - getById: jest.fn(() => TestEditor), + getById: jest.fn(() => () => Promise.resolve(TestEditor)), }; describe('FieldFormatEditor', () => { @@ -34,7 +34,7 @@ describe('FieldFormatEditor', () => { const component = shallow( { const component = shallow( 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; + EditorComponent: LazyExoticComponent | 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 @@ -38,13 +44,13 @@ export class FieldFormatEditor extends PureComponent< 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 ( - + <> {EditorComponent ? ( - + + + + + + } + > + + ) : null} - + ); } } diff --git a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx index b05ddaed064cd..fc55e8a36c99e 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx @@ -253,7 +253,7 @@ export class FieldEditor extends PureComponent { + onFormatParamsChange = (newParams: { [key: string]: any }) => { const { fieldFormatId } = this.state; this.onFormatChange(fieldFormatId as string, newParams); };