Remove dependencies from index pattern field and index pattern list (#75185)

* Remove dependencies from index pattern field and index pattern list
This commit is contained in:
Matthew Kime 2020-09-02 16:00:23 -05:00 committed by GitHub
parent c46e77712a
commit 5467f31640
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
78 changed files with 583 additions and 552 deletions

View file

@ -1,23 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [(constructor)](./kibana-plugin-plugins-data-public.fieldlist._constructor_.md)
## FieldList.(constructor)
Constructs a new instance of the `FieldList` class
<b>Signature:</b>
```typescript
constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: boolean, onNotification?: OnNotification);
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| indexPattern | <code>IndexPattern</code> | |
| specs | <code>FieldSpec[]</code> | |
| shortDotsEnable | <code>boolean</code> | |
| onNotification | <code>OnNotification</code> | |

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [add](./kibana-plugin-plugins-data-public.fieldlist.add.md)
## FieldList.add property
<b>Signature:</b>
```typescript
readonly add: (field: FieldSpec) => void;
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [getAll](./kibana-plugin-plugins-data-public.fieldlist.getall.md)
## FieldList.getAll property
<b>Signature:</b>
```typescript
readonly getAll: () => IndexPatternField[];
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [getByName](./kibana-plugin-plugins-data-public.fieldlist.getbyname.md)
## FieldList.getByName property
<b>Signature:</b>
```typescript
readonly getByName: (name: IndexPatternField['name']) => IndexPatternField | undefined;
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [getByType](./kibana-plugin-plugins-data-public.fieldlist.getbytype.md)
## FieldList.getByType property
<b>Signature:</b>
```typescript
readonly getByType: (type: IndexPatternField['type']) => any[];
```

View file

@ -1,32 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md)
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [fieldList](./kibana-plugin-plugins-data-public.fieldlist.md)
## FieldList class
## fieldList variable
<b>Signature:</b>
```typescript
export declare class FieldList extends Array<IndexPatternField> implements IIndexPatternFieldList
fieldList: (specs?: FieldSpec[], shortDotsEnable?: boolean) => IIndexPatternFieldList
```
## Constructors
| Constructor | Modifiers | Description |
| --- | --- | --- |
| [(constructor)(indexPattern, specs, shortDotsEnable, onNotification)](./kibana-plugin-plugins-data-public.fieldlist._constructor_.md) | | Constructs a new instance of the <code>FieldList</code> class |
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [add](./kibana-plugin-plugins-data-public.fieldlist.add.md) | | <code>(field: FieldSpec) =&gt; void</code> | |
| [getAll](./kibana-plugin-plugins-data-public.fieldlist.getall.md) | | <code>() =&gt; IndexPatternField[]</code> | |
| [getByName](./kibana-plugin-plugins-data-public.fieldlist.getbyname.md) | | <code>(name: IndexPatternField['name']) =&gt; IndexPatternField &#124; undefined</code> | |
| [getByType](./kibana-plugin-plugins-data-public.fieldlist.getbytype.md) | | <code>(type: IndexPatternField['type']) =&gt; any[]</code> | |
| [remove](./kibana-plugin-plugins-data-public.fieldlist.remove.md) | | <code>(field: IFieldType) =&gt; void</code> | |
| [removeAll](./kibana-plugin-plugins-data-public.fieldlist.removeall.md) | | <code>() =&gt; void</code> | |
| [replaceAll](./kibana-plugin-plugins-data-public.fieldlist.replaceall.md) | | <code>(specs: FieldSpec[]) =&gt; void</code> | |
| [toSpec](./kibana-plugin-plugins-data-public.fieldlist.tospec.md) | | <code>() =&gt; {</code><br/><code> count: number;</code><br/><code> script: string &#124; undefined;</code><br/><code> lang: string &#124; undefined;</code><br/><code> conflictDescriptions: Record&lt;string, string[]&gt; &#124; undefined;</code><br/><code> name: string;</code><br/><code> type: string;</code><br/><code> esTypes: string[] &#124; undefined;</code><br/><code> scripted: boolean;</code><br/><code> searchable: boolean;</code><br/><code> aggregatable: boolean;</code><br/><code> readFromDocValues: boolean;</code><br/><code> subType: import(&quot;../types&quot;).IFieldSubType &#124; undefined;</code><br/><code> format: any;</code><br/><code> }[]</code> | |
| [update](./kibana-plugin-plugins-data-public.fieldlist.update.md) | | <code>(field: FieldSpec) =&gt; void</code> | |

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [remove](./kibana-plugin-plugins-data-public.fieldlist.remove.md)
## FieldList.remove property
<b>Signature:</b>
```typescript
readonly remove: (field: IFieldType) => void;
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [removeAll](./kibana-plugin-plugins-data-public.fieldlist.removeall.md)
## FieldList.removeAll property
<b>Signature:</b>
```typescript
readonly removeAll: () => void;
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [replaceAll](./kibana-plugin-plugins-data-public.fieldlist.replaceall.md)
## FieldList.replaceAll property
<b>Signature:</b>
```typescript
readonly replaceAll: (specs: FieldSpec[]) => void;
```

View file

@ -1,25 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [toSpec](./kibana-plugin-plugins-data-public.fieldlist.tospec.md)
## FieldList.toSpec property
<b>Signature:</b>
```typescript
readonly toSpec: () => {
count: number;
script: string | undefined;
lang: string | undefined;
conflictDescriptions: Record<string, string[]> | undefined;
name: string;
type: string;
esTypes: string[] | undefined;
scripted: boolean;
searchable: boolean;
aggregatable: boolean;
readFromDocValues: boolean;
subType: import("../types").IFieldSubType | undefined;
format: any;
}[];
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) &gt; [update](./kibana-plugin-plugins-data-public.fieldlist.update.md)
## FieldList.update property
<b>Signature:</b>
```typescript
readonly update: (field: FieldSpec) => void;
```

View file

@ -28,7 +28,7 @@ export interface IFieldType
| [searchable](./kibana-plugin-plugins-data-public.ifieldtype.searchable.md) | <code>boolean</code> | |
| [sortable](./kibana-plugin-plugins-data-public.ifieldtype.sortable.md) | <code>boolean</code> | |
| [subType](./kibana-plugin-plugins-data-public.ifieldtype.subtype.md) | <code>IFieldSubType</code> | |
| [toSpec](./kibana-plugin-plugins-data-public.ifieldtype.tospec.md) | <code>() =&gt; FieldSpec</code> | |
| [toSpec](./kibana-plugin-plugins-data-public.ifieldtype.tospec.md) | <code>(options?: {</code><br/><code> getFormatterForField?: IndexPattern['getFormatterForField'];</code><br/><code> }) =&gt; FieldSpec</code> | |
| [type](./kibana-plugin-plugins-data-public.ifieldtype.type.md) | <code>string</code> | |
| [visualizable](./kibana-plugin-plugins-data-public.ifieldtype.visualizable.md) | <code>boolean</code> | |

View file

@ -7,5 +7,7 @@
<b>Signature:</b>
```typescript
toSpec?: () => FieldSpec;
toSpec?: (options?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}) => FieldSpec;
```

View file

@ -21,5 +21,6 @@ export interface IIndexPatternFieldList extends Array<IndexPatternField>
| [remove(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.remove.md) | |
| [removeAll()](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md) | |
| [replaceAll(specs)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md) | |
| [toSpec(options)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.tospec.md) | |
| [update(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.update.md) | |

View file

@ -0,0 +1,24 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) &gt; [toSpec](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.tospec.md)
## IIndexPatternFieldList.toSpec() method
<b>Signature:</b>
```typescript
toSpec(options?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}): FieldSpec[];
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| options | <code>{</code><br/><code> getFormatterForField?: IndexPattern['getFormatterForField'];</code><br/><code> }</code> | |
<b>Returns:</b>
`FieldSpec[]`

View file

@ -9,15 +9,13 @@ Constructs a new instance of the `IndexPatternField` class
<b>Signature:</b>
```typescript
constructor(indexPattern: IndexPattern, spec: FieldSpec, displayName: string, onNotification: OnNotification);
constructor(spec: FieldSpec, displayName: string);
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| indexPattern | <code>IndexPattern</code> | |
| spec | <code>FieldSpec</code> | |
| displayName | <code>string</code> | |
| onNotification | <code>OnNotification</code> | |

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) &gt; [format](./kibana-plugin-plugins-data-public.indexpatternfield.format.md)
## IndexPatternField.format property
<b>Signature:</b>
```typescript
get format(): FieldFormat;
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) &gt; [indexPattern](./kibana-plugin-plugins-data-public.indexpatternfield.indexpattern.md)
## IndexPatternField.indexPattern property
<b>Signature:</b>
```typescript
readonly indexPattern: IndexPattern;
```

View file

@ -14,7 +14,7 @@ export declare class IndexPatternField implements IFieldType
| Constructor | Modifiers | Description |
| --- | --- | --- |
| [(constructor)(indexPattern, spec, displayName, onNotification)](./kibana-plugin-plugins-data-public.indexpatternfield._constructor_.md) | | Constructs a new instance of the <code>IndexPatternField</code> class |
| [(constructor)(spec, displayName)](./kibana-plugin-plugins-data-public.indexpatternfield._constructor_.md) | | Constructs a new instance of the <code>IndexPatternField</code> class |
## Properties
@ -26,8 +26,6 @@ export declare class IndexPatternField implements IFieldType
| [displayName](./kibana-plugin-plugins-data-public.indexpatternfield.displayname.md) | | <code>string</code> | |
| [esTypes](./kibana-plugin-plugins-data-public.indexpatternfield.estypes.md) | | <code>string[] &#124; undefined</code> | |
| [filterable](./kibana-plugin-plugins-data-public.indexpatternfield.filterable.md) | | <code>boolean</code> | |
| [format](./kibana-plugin-plugins-data-public.indexpatternfield.format.md) | | <code>FieldFormat</code> | |
| [indexPattern](./kibana-plugin-plugins-data-public.indexpatternfield.indexpattern.md) | | <code>IndexPattern</code> | |
| [lang](./kibana-plugin-plugins-data-public.indexpatternfield.lang.md) | | <code>string &#124; undefined</code> | |
| [name](./kibana-plugin-plugins-data-public.indexpatternfield.name.md) | | <code>string</code> | |
| [readFromDocValues](./kibana-plugin-plugins-data-public.indexpatternfield.readfromdocvalues.md) | | <code>boolean</code> | |
@ -45,5 +43,5 @@ export declare class IndexPatternField implements IFieldType
| Method | Modifiers | Description |
| --- | --- | --- |
| [toJSON()](./kibana-plugin-plugins-data-public.indexpatternfield.tojson.md) | | |
| [toSpec()](./kibana-plugin-plugins-data-public.indexpatternfield.tospec.md) | | |
| [toSpec({ getFormatterForField, })](./kibana-plugin-plugins-data-public.indexpatternfield.tospec.md) | | |

View file

@ -7,7 +7,9 @@
<b>Signature:</b>
```typescript
toSpec(): {
toSpec({ getFormatterForField, }?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}): {
count: number;
script: string | undefined;
lang: string | undefined;
@ -20,9 +22,19 @@ toSpec(): {
aggregatable: boolean;
readFromDocValues: boolean;
subType: import("../types").IFieldSubType | undefined;
format: any;
format: {
id: any;
params: any;
} | undefined;
};
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| { getFormatterForField, } | <code>{</code><br/><code> getFormatterForField?: IndexPattern['getFormatterForField'];</code><br/><code> }</code> | |
<b>Returns:</b>
`{
@ -38,6 +50,9 @@ toSpec(): {
aggregatable: boolean;
readFromDocValues: boolean;
subType: import("../types").IFieldSubType | undefined;
format: any;
format: {
id: any;
params: any;
} | undefined;
}`

View file

@ -10,7 +10,6 @@
| --- | --- |
| [AggParamType](./kibana-plugin-plugins-data-public.aggparamtype.md) | |
| [FieldFormat](./kibana-plugin-plugins-data-public.fieldformat.md) | |
| [FieldList](./kibana-plugin-plugins-data-public.fieldlist.md) | |
| [FilterManager](./kibana-plugin-plugins-data-public.filtermanager.md) | |
| [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) | |
| [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) | |
@ -103,6 +102,7 @@
| [expandShorthand](./kibana-plugin-plugins-data-public.expandshorthand.md) | |
| [extractSearchSourceReferences](./kibana-plugin-plugins-data-public.extractsearchsourcereferences.md) | |
| [fieldFormats](./kibana-plugin-plugins-data-public.fieldformats.md) | |
| [fieldList](./kibana-plugin-plugins-data-public.fieldlist.md) | |
| [FilterBar](./kibana-plugin-plugins-data-public.filterbar.md) | |
| [getKbnTypeNames](./kibana-plugin-plugins-data-public.getkbntypenames.md) | Get the esTypes known by all kbnFieldTypes {<!-- -->Array<string>} |
| [indexPatterns](./kibana-plugin-plugins-data-public.indexpatterns.md) | |

View file

@ -28,7 +28,7 @@ export interface IFieldType
| [searchable](./kibana-plugin-plugins-data-server.ifieldtype.searchable.md) | <code>boolean</code> | |
| [sortable](./kibana-plugin-plugins-data-server.ifieldtype.sortable.md) | <code>boolean</code> | |
| [subType](./kibana-plugin-plugins-data-server.ifieldtype.subtype.md) | <code>IFieldSubType</code> | |
| [toSpec](./kibana-plugin-plugins-data-server.ifieldtype.tospec.md) | <code>() =&gt; FieldSpec</code> | |
| [toSpec](./kibana-plugin-plugins-data-server.ifieldtype.tospec.md) | <code>(options?: {</code><br/><code> getFormatterForField?: IndexPattern['getFormatterForField'];</code><br/><code> }) =&gt; FieldSpec</code> | |
| [type](./kibana-plugin-plugins-data-server.ifieldtype.type.md) | <code>string</code> | |
| [visualizable](./kibana-plugin-plugins-data-server.ifieldtype.visualizable.md) | <code>boolean</code> | |

View file

@ -7,5 +7,7 @@
<b>Signature:</b>
```typescript
toSpec?: () => FieldSpec;
toSpec?: (options?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}) => FieldSpec;
```

View file

@ -7,6 +7,7 @@
import { Action } from 'history';
import { ApiResponse } from '@elastic/elasticsearch/lib/Transport';
import Boom from 'boom';
import { ErrorToastOptions as ErrorToastOptions_2 } from 'src/core/public/notifications';
import { EuiBreadcrumb } from '@elastic/eui';
import { EuiButtonEmptyProps } from '@elastic/eui';
import { EuiConfirmModalProps } from '@elastic/eui';
@ -27,7 +28,9 @@ import { PublicUiSettingsParams as PublicUiSettingsParams_2 } from 'src/core/ser
import React from 'react';
import { RecursiveReadonly } from '@kbn/utility-types';
import * as Rx from 'rxjs';
import { SavedObject as SavedObject_2 } from 'src/core/server';
import { ShallowPromise } from '@kbn/utility-types';
import { ToastInputFields as ToastInputFields_2 } from 'src/core/public/notifications';
import { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport';
import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport';
import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport';

View file

@ -40,6 +40,7 @@ import { DeleteScriptParams } from 'elasticsearch';
import { DeleteTemplateParams } from 'elasticsearch';
import { DetailedPeerCertificate } from 'tls';
import { Duration } from 'moment';
import { ErrorToastOptions } from 'src/core/public/notifications';
import { ExistsParams } from 'elasticsearch';
import { ExplainParams } from 'elasticsearch';
import { FieldStatsParams } from 'elasticsearch';
@ -118,6 +119,7 @@ import { RenderSearchTemplateParams } from 'elasticsearch';
import { Request } from 'hapi';
import { ResponseObject } from 'hapi';
import { ResponseToolkit } from 'hapi';
import { SavedObject as SavedObject_2 } from 'src/core/server';
import { SchemaTypeError } from '@kbn/config-schema';
import { ScrollParams } from 'elasticsearch';
import { SearchParams } from 'elasticsearch';
@ -141,6 +143,7 @@ import { TasksCancelParams } from 'elasticsearch';
import { TasksGetParams } from 'elasticsearch';
import { TasksListParams } from 'elasticsearch';
import { TermvectorsParams } from 'elasticsearch';
import { ToastInputFields } from 'src/core/public/notifications';
import { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport';
import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport';
import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport';

View file

@ -17,30 +17,26 @@
* under the License.
*/
import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
import { IIndexPattern, IFieldType } from '../..';
import { IIndexPattern } from '../..';
import { getIndexPatternFromFilter } from './get_index_pattern_from_filter';
import { Filter } from '../filters';
function getValueFormatter(indexPattern?: IIndexPattern, key?: string) {
if (!indexPattern || !key) return;
// checking getFormatterForField exists because there is at least once case where an index pattern
// is an object rather than an IndexPattern class
if (!indexPattern || !indexPattern.getFormatterForField || !key) return;
let format = get(indexPattern, ['fields', 'byName', key, 'format']);
if (!format && (indexPattern.fields as any).getByName) {
// TODO: Why is indexPatterns sometimes a map and sometimes an array?
const field: IFieldType = (indexPattern.fields as any).getByName(key);
if (!field) {
throw new Error(
i18n.translate('data.filter.filterBar.fieldNotFound', {
defaultMessage: 'Field {key} not found in index pattern {indexPattern}',
values: { key, indexPattern: indexPattern.title },
})
);
}
format = field.format;
const field = indexPattern.fields.find((f) => f.name === key);
if (!field) {
throw new Error(
i18n.translate('data.filter.filterBar.fieldNotFound', {
defaultMessage: 'Field {key} not found in index pattern {indexPattern}',
values: { key, indexPattern: indexPattern.title },
})
);
}
return format;
return indexPattern.getFormatterForField(field);
}
export function getDisplayValueFromFilter(filter: Filter, indexPatterns: IIndexPattern[]): string {

View file

@ -60,7 +60,7 @@ export class SourceFormat extends FieldFormat {
textConvert: TextContextTypeConvert = (value) => JSON.stringify(value);
htmlConvert: HtmlContextTypeConvert = (value, options = {}) => {
const { field, hit } = options;
const { field, hit, indexPattern } = options;
if (!field) {
const converter = this.getConverterFor('text') as Function;
@ -69,7 +69,7 @@ export class SourceFormat extends FieldFormat {
}
const highlights = (hit && hit.highlight) || {};
const formatted = field.indexPattern.formatHit(hit);
const formatted = indexPattern.formatHit(hit);
const highlightPairs: any[] = [];
const sourcePairs: any[] = [];
const isShortDots = this.getConfig!(UI_SETTINGS.SHORT_DOTS_ENABLE);

View file

@ -181,11 +181,11 @@ export class FieldFormatsRegistry {
* @param {ES_FIELD_TYPES[]} esTypes
* @return {FieldFormat}
*/
getDefaultInstancePlain(
getDefaultInstancePlain = (
fieldType: KBN_FIELD_TYPES,
esTypes?: ES_FIELD_TYPES[],
params: Record<string, any> = {}
): FieldFormat {
): FieldFormat => {
const conf = this.getDefaultConfig(fieldType, esTypes);
const instanceParams = {
...conf.params,
@ -193,7 +193,7 @@ export class FieldFormatsRegistry {
};
return this.getInstance(conf.id, instanceParams);
}
};
/**
* Returns a cache key built by the given variables for caching in memoized
* Where esType contains fieldType, fieldType is returned

View file

@ -27,6 +27,7 @@ export type FieldFormatsContentType = 'html' | 'text';
/** @internal **/
export interface HtmlContextTypeOptions {
field?: any;
indexPattern?: any;
hit?: Record<string, any>;
}

View file

@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { FieldSpec } from './types';
export class FieldTypeUnknownError extends Error {
public readonly fieldSpec: FieldSpec;
constructor(message: string, spec: FieldSpec) {
super(message);
this.name = 'FieldTypeUnknownError';
this.fieldSpec = spec;
}
}

View file

@ -14,7 +14,7 @@ Object {
},
"count": 1,
"esTypes": Array [
"type",
"text",
],
"lang": "lang",
"name": "name",
@ -30,7 +30,7 @@ Object {
"path": "path",
},
},
"type": "type",
"type": "string",
}
`;
@ -48,7 +48,7 @@ Object {
},
"count": 1,
"esTypes": Array [
"type",
"text",
],
"format": Object {
"id": "number",
@ -70,6 +70,6 @@ Object {
"path": "path",
},
},
"type": "type",
"type": "string",
}
`;

View file

@ -35,6 +35,7 @@ export interface IIndexPatternFieldList extends Array<IndexPatternField> {
removeAll(): void;
replaceAll(specs: FieldSpec[]): void;
update(field: FieldSpec): void;
toSpec(options?: { getFormatterForField?: IndexPattern['getFormatterForField'] }): FieldSpec[];
}
export type CreateIndexPatternFieldList = (
@ -44,87 +45,79 @@ export type CreateIndexPatternFieldList = (
onNotification?: OnNotification
) => IIndexPatternFieldList;
export class FieldList extends Array<IndexPatternField> implements IIndexPatternFieldList {
private byName: FieldMap = new Map();
private groups: Map<IndexPatternField['type'], FieldMap> = new Map();
private indexPattern: IndexPattern;
private shortDotsEnable: boolean;
private onNotification: OnNotification;
private setByName = (field: IndexPatternField) => this.byName.set(field.name, field);
private setByGroup = (field: IndexPatternField) => {
if (typeof this.groups.get(field.type) === 'undefined') {
this.groups.set(field.type, new Map());
// extending the array class and using a constructor doesn't work well
// when calling filter and similar so wrapping in a callback.
// to be removed in the future
export const fieldList = (
specs: FieldSpec[] = [],
shortDotsEnable = false
): IIndexPatternFieldList => {
class FldList extends Array<IndexPatternField> implements IIndexPatternFieldList {
private byName: FieldMap = new Map();
private groups: Map<IndexPatternField['type'], FieldMap> = new Map();
private setByName = (field: IndexPatternField) => this.byName.set(field.name, field);
private setByGroup = (field: IndexPatternField) => {
if (typeof this.groups.get(field.type) === 'undefined') {
this.groups.set(field.type, new Map());
}
this.groups.get(field.type)!.set(field.name, field);
};
private removeByGroup = (field: IFieldType) => this.groups.get(field.type)!.delete(field.name);
private calcDisplayName = (name: string) =>
shortDotsEnable ? shortenDottedString(name) : name;
constructor() {
super();
specs.map((field) => this.add(field));
}
this.groups.get(field.type)!.set(field.name, field);
};
private removeByGroup = (field: IFieldType) => this.groups.get(field.type)!.delete(field.name);
private calcDisplayName = (name: string) =>
this.shortDotsEnable ? shortenDottedString(name) : name;
constructor(
indexPattern: IndexPattern,
specs: FieldSpec[] = [],
shortDotsEnable = false,
onNotification: OnNotification = () => {}
) {
super();
this.indexPattern = indexPattern;
this.shortDotsEnable = shortDotsEnable;
this.onNotification = onNotification;
specs.map((field) => this.add(field));
public readonly getAll = () => [...this.byName.values()];
public readonly getByName = (name: IndexPatternField['name']) => this.byName.get(name);
public readonly getByType = (type: IndexPatternField['type']) => [
...(this.groups.get(type) || new Map()).values(),
];
public readonly add = (field: FieldSpec) => {
const newField = new IndexPatternField(field, this.calcDisplayName(field.name));
this.push(newField);
this.setByName(newField);
this.setByGroup(newField);
};
public readonly remove = (field: IFieldType) => {
this.removeByGroup(field);
this.byName.delete(field.name);
const fieldIndex = findIndex(this, { name: field.name });
this.splice(fieldIndex, 1);
};
public readonly update = (field: FieldSpec) => {
const newField = new IndexPatternField(field, this.calcDisplayName(field.name));
const index = this.findIndex((f) => f.name === newField.name);
this.splice(index, 1, newField);
this.setByName(newField);
this.removeByGroup(newField);
this.setByGroup(newField);
};
public readonly removeAll = () => {
this.length = 0;
this.byName.clear();
this.groups.clear();
};
public readonly replaceAll = (spcs: FieldSpec[]) => {
this.removeAll();
spcs.forEach(this.add);
};
public toSpec({
getFormatterForField,
}: {
getFormatterForField?: IndexPattern['getFormatterForField'];
} = {}) {
return [...this.map((field) => field.toSpec({ getFormatterForField }))];
}
}
public readonly getAll = () => [...this.byName.values()];
public readonly getByName = (name: IndexPatternField['name']) => this.byName.get(name);
public readonly getByType = (type: IndexPatternField['type']) => [
...(this.groups.get(type) || new Map()).values(),
];
public readonly add = (field: FieldSpec) => {
const newField = new IndexPatternField(
this.indexPattern,
field,
this.calcDisplayName(field.name),
this.onNotification
);
this.push(newField);
this.setByName(newField);
this.setByGroup(newField);
};
public readonly remove = (field: IFieldType) => {
this.removeByGroup(field);
this.byName.delete(field.name);
const fieldIndex = findIndex(this, { name: field.name });
this.splice(fieldIndex, 1);
};
public readonly update = (field: FieldSpec) => {
const newField = new IndexPatternField(
this.indexPattern,
field,
this.calcDisplayName(field.name),
this.onNotification
);
const index = this.findIndex((f) => f.name === newField.name);
this.splice(index, 1, newField);
this.setByName(newField);
this.removeByGroup(newField);
this.setByGroup(newField);
};
public readonly removeAll = () => {
this.length = 0;
this.byName.clear();
this.groups.clear();
};
public readonly replaceAll = (specs: FieldSpec[]) => {
this.removeAll();
specs.forEach(this.add);
};
public readonly toSpec = () => {
return [...this.map((field) => field.toSpec())];
};
}
return new FldList();
};

View file

@ -19,7 +19,7 @@
import { IndexPatternField } from './index_pattern_field';
import { IndexPattern } from '../index_patterns';
import { KBN_FIELD_TYPES } from '../../../common';
import { KBN_FIELD_TYPES, FieldFormat } from '../../../common';
import { FieldSpec } from '../types';
describe('Field', function () {
@ -28,21 +28,16 @@ describe('Field', function () {
}
function getField(values = {}) {
return new IndexPatternField(
fieldValues.indexPattern as IndexPattern,
{ ...fieldValues, ...values },
'displayName',
() => {}
);
return new IndexPatternField({ ...fieldValues, ...values }, 'displayName');
}
const fieldValues = {
name: 'name',
type: 'type',
type: 'string',
script: 'script',
lang: 'lang',
count: 1,
esTypes: ['type'],
esTypes: ['text'],
aggregatable: true,
filterable: true,
searchable: true,
@ -125,7 +120,7 @@ describe('Field', function () {
const fieldB = getField({ indexed: true, type: KBN_FIELD_TYPES.STRING });
expect(fieldB.sortable).toEqual(true);
const fieldC = getField({ indexed: false });
const fieldC = getField({ indexed: false, aggregatable: false, scripted: false });
expect(fieldC.sortable).toEqual(false);
});
@ -139,31 +134,26 @@ describe('Field', function () {
const fieldC = getField({ indexed: true, type: KBN_FIELD_TYPES.STRING });
expect(fieldC.filterable).toEqual(true);
const fieldD = getField({ scripted: false, indexed: false });
const fieldD = getField({ scripted: false, indexed: false, searchable: false });
expect(fieldD.filterable).toEqual(false);
});
it('exports the property to JSON', () => {
const field = new IndexPatternField(
{ fieldFormatMap: { name: {} } } as IndexPattern,
fieldValues,
'displayName',
() => {}
);
const field = new IndexPatternField(fieldValues, 'displayName');
expect(flatten(field)).toMatchSnapshot();
});
it('spec snapshot', () => {
const field = new IndexPatternField(
{
fieldFormatMap: {
name: { toJSON: () => ({ id: 'number', params: { pattern: '$0,0.[00]' } }) },
},
} as IndexPattern,
fieldValues,
'displayName',
() => {}
);
expect(field.toSpec()).toMatchSnapshot();
const field = new IndexPatternField(fieldValues, 'displayName');
const getFormatterForField = () =>
({
toJSON: () => ({
id: 'number',
params: {
pattern: '$0,0.[00]',
},
}),
} as FieldFormat);
expect(field.toSpec({ getFormatterForField })).toMatchSnapshot();
});
});

View file

@ -20,40 +20,27 @@
import { i18n } from '@kbn/i18n';
import { KbnFieldType, getKbnFieldType } from '../../kbn_field_types';
import { KBN_FIELD_TYPES } from '../../kbn_field_types/types';
import { FieldFormat } from '../../field_formats';
import { IFieldType } from './types';
import { OnNotification, FieldSpec } from '../types';
import { IndexPattern } from '../index_patterns';
import { FieldSpec, IndexPattern } from '../..';
import { FieldTypeUnknownError } from '../errors';
export class IndexPatternField implements IFieldType {
readonly spec: FieldSpec;
// not writable or serialized
readonly indexPattern: IndexPattern;
readonly displayName: string;
private readonly kbnFieldType: KbnFieldType;
constructor(
indexPattern: IndexPattern,
spec: FieldSpec,
displayName: string,
onNotification: OnNotification
) {
this.indexPattern = indexPattern;
constructor(spec: FieldSpec, displayName: string) {
this.spec = { ...spec, type: spec.name === '_source' ? '_source' : spec.type };
this.displayName = displayName;
this.kbnFieldType = getKbnFieldType(spec.type);
if (spec.type && this.kbnFieldType?.name === KBN_FIELD_TYPES.UNKNOWN) {
const title = i18n.translate('data.indexPatterns.unknownFieldHeader', {
values: { type: spec.type },
defaultMessage: 'Unknown field type {type}',
const msg = i18n.translate('data.indexPatterns.unknownFieldTypeErrorMsg', {
values: { type: spec.type, name: spec.name },
defaultMessage: `Field '{name}' Unknown field type '{type}'`,
});
const text = i18n.translate('data.indexPatterns.unknownFieldErrorMessage', {
values: { name: spec.name, title: indexPattern.title },
defaultMessage: 'Field {name} in indexPattern {title} is using an unknown field type.',
});
onNotification({ title, text, color: 'danger', iconType: 'alert' });
throw new FieldTypeUnknownError(msg, spec);
}
}
@ -143,10 +130,6 @@ export class IndexPatternField implements IFieldType {
return this.aggregatable;
}
public get format(): FieldFormat {
return this.indexPattern.getFormatterForField(this);
}
public toJSON() {
return {
count: this.count,
@ -165,7 +148,11 @@ export class IndexPatternField implements IFieldType {
};
}
public toSpec() {
public toSpec({
getFormatterForField,
}: {
getFormatterForField?: IndexPattern['getFormatterForField'];
} = {}) {
return {
count: this.count,
script: this.script,
@ -179,7 +166,7 @@ export class IndexPatternField implements IFieldType {
aggregatable: this.aggregatable,
readFromDocValues: this.readFromDocValues,
subType: this.subType,
format: this.indexPattern?.fieldFormatMap[this.name]?.toJSON() || undefined,
format: getFormatterForField ? getFormatterForField(this).toJSON() : undefined,
};
}
}

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { FieldSpec, IFieldSubType } from '../types';
import { FieldSpec, IFieldSubType, IndexPattern } from '../..';
export interface IFieldType {
name: string;
@ -38,5 +38,5 @@ export interface IFieldType {
subType?: IFieldSubType;
displayName?: string;
format?: any;
toSpec?: () => FieldSpec;
toSpec?: (options?: { getFormatterForField?: IndexPattern['getFormatterForField'] }) => FieldSpec;
}

View file

@ -20,3 +20,5 @@
export * from './fields';
export * from './types';
export { IndexPatternsService } from './index_patterns';
export type { IndexPattern } from './index_patterns';
export * from './errors';

View file

@ -32,7 +32,12 @@ Object {
"esTypes": Array [
"boolean",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "ssl",
"readFromDocValues": true,
@ -49,7 +54,12 @@ Object {
"esTypes": Array [
"date",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "@timestamp",
"readFromDocValues": true,
@ -66,7 +76,12 @@ Object {
"esTypes": Array [
"date",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "time",
"readFromDocValues": true,
@ -83,7 +98,12 @@ Object {
"esTypes": Array [
"keyword",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "@tags",
"readFromDocValues": true,
@ -100,7 +120,12 @@ Object {
"esTypes": Array [
"date",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "utc_time",
"readFromDocValues": true,
@ -117,7 +142,12 @@ Object {
"esTypes": Array [
"integer",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "phpmemory",
"readFromDocValues": true,
@ -134,7 +164,12 @@ Object {
"esTypes": Array [
"ip",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "ip",
"readFromDocValues": true,
@ -151,7 +186,12 @@ Object {
"esTypes": Array [
"attachment",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "request_body",
"readFromDocValues": true,
@ -168,7 +208,12 @@ Object {
"esTypes": Array [
"geo_point",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "point",
"readFromDocValues": true,
@ -185,7 +230,12 @@ Object {
"esTypes": Array [
"geo_shape",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "area",
"readFromDocValues": false,
@ -202,7 +252,12 @@ Object {
"esTypes": Array [
"murmur3",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "hashed",
"readFromDocValues": false,
@ -219,7 +274,12 @@ Object {
"esTypes": Array [
"geo_point",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "geo.coordinates",
"readFromDocValues": true,
@ -236,7 +296,12 @@ Object {
"esTypes": Array [
"text",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "extension",
"readFromDocValues": false,
@ -253,7 +318,12 @@ Object {
"esTypes": Array [
"keyword",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "extension.keyword",
"readFromDocValues": true,
@ -274,7 +344,12 @@ Object {
"esTypes": Array [
"text",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "machine.os",
"readFromDocValues": false,
@ -291,7 +366,12 @@ Object {
"esTypes": Array [
"keyword",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "machine.os.raw",
"readFromDocValues": true,
@ -312,7 +392,12 @@ Object {
"esTypes": Array [
"keyword",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "geo.src",
"readFromDocValues": true,
@ -329,7 +414,12 @@ Object {
"esTypes": Array [
"_id",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "_id",
"readFromDocValues": false,
@ -346,7 +436,12 @@ Object {
"esTypes": Array [
"_type",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "_type",
"readFromDocValues": false,
@ -363,7 +458,12 @@ Object {
"esTypes": Array [
"_source",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "_source",
"readFromDocValues": false,
@ -380,7 +480,12 @@ Object {
"esTypes": Array [
"text",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "non-filterable",
"readFromDocValues": false,
@ -397,7 +502,12 @@ Object {
"esTypes": Array [
"text",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "non-sortable",
"readFromDocValues": false,
@ -414,7 +524,12 @@ Object {
"esTypes": Array [
"conflict",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": undefined,
"name": "custom_user_field",
"readFromDocValues": true,
@ -431,7 +546,12 @@ Object {
"esTypes": Array [
"text",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": "expression",
"name": "script string",
"readFromDocValues": false,
@ -448,7 +568,12 @@ Object {
"esTypes": Array [
"long",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": "expression",
"name": "script number",
"readFromDocValues": false,
@ -465,7 +590,12 @@ Object {
"esTypes": Array [
"date",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": "painless",
"name": "script date",
"readFromDocValues": false,
@ -482,7 +612,12 @@ Object {
"esTypes": Array [
"murmur3",
],
"format": undefined,
"format": Object {
"id": "number",
"params": Object {
"pattern": "$0,0.[00]",
},
},
"lang": "expression",
"name": "script murmur3",
"readFromDocValues": false,

View file

@ -34,9 +34,9 @@ export function formatHitProvider(indexPattern: IndexPattern, defaultFormat: any
type: FieldFormatsContentType = 'html'
) {
const field = indexPattern.fields.getByName(fieldName);
const format = field ? field.format : defaultFormat;
const format = field ? indexPattern.getFormatterForField(field) : defaultFormat;
return format.convert(val, type, { field, hit });
return format.convert(val, type, { field, hit, indexPattern });
}
function formatHit(hit: Record<string, any>, type: string = 'html') {

View file

@ -29,6 +29,7 @@ import { stubbedSavedObjectIndexPattern } from '../../../../../fixtures/stubbed_
import { IndexPatternField } from '../fields';
import { fieldFormatsMock } from '../../field_formats/mocks';
import { FieldFormat } from '../..';
class MockFieldFormatter {}
@ -170,7 +171,6 @@ describe('IndexPattern', () => {
test('should have expected properties on fields', function () {
expect(indexPattern.fields[0]).toHaveProperty('displayName');
expect(indexPattern.fields[0]).toHaveProperty('filterable');
expect(indexPattern.fields[0]).toHaveProperty('format');
expect(indexPattern.fields[0]).toHaveProperty('sortable');
expect(indexPattern.fields[0]).toHaveProperty('scripted');
});
@ -319,16 +319,18 @@ describe('IndexPattern', () => {
describe('toSpec', () => {
test('should match snapshot', () => {
indexPattern.fieldFormatMap.bytes = {
const formatter = {
toJSON: () => ({ id: 'number', params: { pattern: '$0,0.[00]' } }),
};
} as FieldFormat;
indexPattern.getFormatterForField = () => formatter;
expect(indexPattern.toSpec()).toMatchSnapshot();
});
test('can restore from spec', async () => {
indexPattern.fieldFormatMap.bytes = {
const formatter = {
toJSON: () => ({ id: 'number', params: { pattern: '$0,0.[00]' } }),
};
} as FieldFormat;
indexPattern.getFormatterForField = () => formatter;
const spec = indexPattern.toSpec();
const restoredPattern = await create(spec.id as string);
restoredPattern.initFromSpec(spec);

View file

@ -26,11 +26,12 @@ import {
ES_FIELD_TYPES,
KBN_FIELD_TYPES,
IIndexPattern,
FieldTypeUnknownError,
FieldFormatNotFoundError,
} from '../../../common';
import { findByTitle } from '../utils';
import { IndexPatternMissingIndices } from '../lib';
import { IndexPatternField, IIndexPatternFieldList, FieldList } from '../fields';
import { IndexPatternField, IIndexPatternFieldList, fieldList } from '../fields';
import { createFieldsFetcher } from './_fields_fetcher';
import { formatHitProvider } from './format_hit';
import { flattenHitWrapper } from './flatten_hit';
@ -125,8 +126,7 @@ export class IndexPattern implements IIndexPattern {
this.shortDotsEnable = shortDotsEnable;
this.metaFields = metaFields;
this.fields = new FieldList(this, [], this.shortDotsEnable, this.onNotification);
this.fields = fieldList([], this.shortDotsEnable);
this.apiClient = apiClient;
this.fieldsFetcher = createFieldsFetcher(this, apiClient, metaFields);
@ -138,6 +138,22 @@ export class IndexPattern implements IIndexPattern {
this.formatField = this.formatHit.formatField;
}
private unknownFieldErrorNotification(
fieldType: string,
fieldName: string,
indexPatternTitle: string
) {
const title = i18n.translate('data.indexPatterns.unknownFieldHeader', {
values: { type: fieldType },
defaultMessage: 'Unknown field type {type}',
});
const text = i18n.translate('data.indexPatterns.unknownFieldErrorMessage', {
values: { name: fieldName, title: indexPatternTitle },
defaultMessage: 'Field {name} in indexPattern {title} is using an unknown field type.',
});
this.onNotification({ title, text, color: 'danger', iconType: 'alert' });
}
private serializeFieldFormatMap(flat: any, format: string, field: string | undefined) {
if (format && field) {
flat[field] = format;
@ -181,7 +197,15 @@ export class IndexPattern implements IIndexPattern {
await this.refreshFields();
} else {
if (specs) {
this.fields.replaceAll(specs);
try {
this.fields.replaceAll(specs);
} catch (err) {
if (err instanceof FieldTypeUnknownError) {
this.unknownFieldErrorNotification(err.fieldSpec.name, err.fieldSpec.type, this.title);
} else {
throw err;
}
}
}
}
}
@ -203,7 +227,15 @@ export class IndexPattern implements IIndexPattern {
this.timeFieldName = spec.timeFieldName;
this.sourceFilters = spec.sourceFilters;
this.fields.replaceAll(spec.fields || []);
try {
this.fields.replaceAll(spec.fields || []);
} catch (err) {
if (err instanceof FieldTypeUnknownError) {
this.unknownFieldErrorNotification(err.fieldSpec.name, err.fieldSpec.type, this.title);
} else {
throw err;
}
}
this.typeMeta = spec.typeMeta;
this.fieldFormatMap = _.mapValues(fieldFormatMap, (mapping) => {
@ -322,7 +354,7 @@ export class IndexPattern implements IIndexPattern {
title: this.title,
timeFieldName: this.timeFieldName,
sourceFilters: this.sourceFilters,
fields: this.fields.toSpec(),
fields: this.fields.toSpec({ getFormatterForField: this.getFormatterForField.bind(this) }),
typeMeta: this.typeMeta,
};
}
@ -342,19 +374,27 @@ export class IndexPattern implements IIndexPattern {
throw new DuplicateField(name);
}
this.fields.add({
name,
script,
type: fieldType,
scripted: true,
lang,
aggregatable: true,
searchable: true,
count: 0,
readFromDocValues: false,
});
try {
this.fields.add({
name,
script,
type: fieldType,
scripted: true,
lang,
aggregatable: true,
searchable: true,
count: 0,
readFromDocValues: false,
});
} catch (err) {
if (err instanceof FieldTypeUnknownError) {
this.unknownFieldErrorNotification(err.fieldSpec.name, err.fieldSpec.type, this.title);
} else {
throw err;
}
await this.save();
await this.save();
}
}
removeScriptedField(fieldName: string) {
@ -572,7 +612,15 @@ export class IndexPattern implements IIndexPattern {
async _fetchFields() {
const fields = await this.fieldsFetcher.fetch(this);
const scripted = this.getScriptedFields().map((field) => field.spec);
this.fields.replaceAll([...fields, ...scripted]);
try {
this.fields.replaceAll([...fields, ...scripted]);
} catch (err) {
if (err instanceof FieldTypeUnknownError) {
this.unknownFieldErrorNotification(err.fieldSpec.name, err.fieldSpec.type, this.title);
} else {
throw err;
}
}
}
refreshFields() {

View file

@ -25,7 +25,6 @@ import {
createEnsureDefaultIndexPattern,
EnsureDefaultIndexPattern,
} from './ensure_default_index_pattern';
import { IndexPatternField } from '../fields';
import {
OnNotification,
OnError,
@ -86,15 +85,6 @@ export class IndexPatternsService {
);
}
public createField(
indexPattern: IndexPattern,
spec: IndexPatternField['spec'],
displayName: string,
onNotification: OnNotification
) {
return new IndexPatternField(indexPattern, spec, displayName, onNotification);
}
private async refreshSavedObjectsCache() {
this.savedObjectsCache = await this.savedObjectsClient.find<IndexPatternSavedObjectAttrs>({
type: 'index-pattern',

View file

@ -25,8 +25,7 @@ import { AggType } from './agg_type';
import { AggTypesRegistryStart } from './agg_types_registry';
import { mockAggTypesRegistry } from './test_helpers';
import { MetricAggType } from './metrics/metric_agg_type';
import { IndexPattern } from '../../index_patterns/index_patterns/index_pattern';
import { IIndexPatternFieldList } from '../../index_patterns/fields';
import { IndexPattern, IndexPatternField, IIndexPatternFieldList } from '../../index_patterns';
describe('AggConfig', () => {
let indexPattern: IndexPattern;
@ -67,6 +66,9 @@ describe('AggConfig', () => {
getByName: (name: string) => fields.find((f) => f.name === name),
filter: () => fields,
} as unknown) as IndexPattern['fields'],
getFormatterForField: (field: IndexPatternField) => ({
toJSON: () => ({}),
}),
} as IndexPattern;
typesRegistry = mockAggTypesRegistry();
});

View file

@ -147,6 +147,9 @@ describe('AggType Class', () => {
},
},
},
aggConfigs: {
indexPattern: { getFormatterForField: () => ({ toJSON: () => ({ id: 'format' }) }) },
},
} as unknown) as IAggConfig;
const aggType = new AggType({
name: 'name',

View file

@ -271,7 +271,9 @@ export class AggType<
this.getSerializedFormat =
config.getSerializedFormat ||
((agg: TAggConfig) => {
return agg.params.field ? agg.params.field.format.toJSON() : {};
return agg.params.field
? agg.aggConfigs.indexPattern.getFormatterForField(agg.params.field).toJSON()
: {};
});
this.getValue = config.getValue || ((agg: TAggConfig, bucket: any) => {});

View file

@ -140,7 +140,7 @@ export const buildOtherBucketAgg = (
const bucketAggs = aggConfigs.aggs.filter((agg) => agg.type.type === AggGroupNames.Buckets);
const index = bucketAggs.findIndex((agg) => agg.id === aggWithOtherBucket.id);
const aggs = aggConfigs.toDsl();
const indexPattern = aggWithOtherBucket.params.field.indexPattern;
const indexPattern = aggWithOtherBucket.aggConfigs.indexPattern;
// create filters aggregation
const filterAgg = aggConfigs.createAggConfig(
@ -211,7 +211,7 @@ export const buildOtherBucketAgg = (
filters.push(
buildExistsFilter(
aggWithOtherBucket.params.field,
aggWithOtherBucket.params.field.indexPattern
aggWithOtherBucket.aggConfigs.indexPattern
)
);
}
@ -264,7 +264,7 @@ export const mergeOtherBucketAggResponse = (
const phraseFilter = buildPhrasesFilter(
otherAgg.params.field,
requestFilterTerms,
otherAgg.params.field.indexPattern
otherAgg.aggConfigs.indexPattern
);
phraseFilter.meta.negate = true;
bucket.filters = [phraseFilter];
@ -276,7 +276,7 @@ export const mergeOtherBucketAggResponse = (
)
) {
bucket.filters.push(
buildExistsFilter(otherAgg.params.field, otherAgg.params.field.indexPattern)
buildExistsFilter(otherAgg.params.field, otherAgg.aggConfigs.indexPattern)
);
}
aggResultBuckets.push(bucket);

View file

@ -40,6 +40,7 @@ describe('AggConfig Filters', () => {
getByName: () => field,
filter: () => [field],
},
getFormatterForField: () => new BytesFormat({}, getConfig),
} as any;
return new AggConfigs(

View file

@ -30,7 +30,6 @@ describe('AggConfig Filters', () => {
const getAggConfigs = () => {
const field = {
name: 'bytes',
format: new BytesFormat({}, getConfig),
};
const indexPattern = {
@ -40,6 +39,7 @@ describe('AggConfig Filters', () => {
getByName: () => field,
filter: () => [field],
},
getFormatterForField: () => new BytesFormat({}, getConfig),
} as any;
return new AggConfigs(

View file

@ -27,7 +27,7 @@ import {
export const createFilterTerms = (aggConfig: IBucketAggConfig, key: string, params: any) => {
const field = aggConfig.params.field;
const indexPattern = field.indexPattern;
const indexPattern = aggConfig.aggConfigs.indexPattern;
if (key === '__other__') {
const terms = params.terms;

View file

@ -58,7 +58,9 @@ export const getDateRangeBucketAgg = ({
getSerializedFormat(agg) {
return {
id: 'date_range',
params: agg.params.field ? agg.params.field.format.toJSON() : {},
params: agg.params.field
? agg.aggConfigs.indexPattern.getFormatterForField(agg.params.field).toJSON()
: {},
};
},
makeLabel(aggConfig) {

View file

@ -59,7 +59,9 @@ export const getIpRangeBucketAgg = () =>
getSerializedFormat(agg) {
return {
id: 'ip_range',
params: agg.params.field ? agg.params.field.format.toJSON() : {},
params: agg.params.field
? agg.aggConfigs.indexPattern.getFormatterForField(agg.params.field).toJSON()
: {},
};
},
makeLabel(aggConfig) {

View file

@ -27,12 +27,6 @@ describe('Range Agg', () => {
const getAggConfigs = () => {
const field = {
name: 'bytes',
format: new NumberFormat(
{
pattern: '0,0.[000] b',
},
getConfig
),
};
const indexPattern = {
@ -42,6 +36,13 @@ describe('Range Agg', () => {
getByName: () => field,
filter: () => [field],
},
getFormatterForField: () =>
new NumberFormat(
{
pattern: '0,0.[000] b',
},
getConfig
),
} as any;
return new AggConfigs(

View file

@ -78,7 +78,9 @@ export const getRangeBucketAgg = ({ getFieldFormatsStart }: RangeBucketAggDepend
return key;
},
getSerializedFormat(agg) {
const format = agg.params.field ? agg.params.field.format.toJSON() : {};
const format = agg.params.field
? agg.aggConfigs.indexPattern.getFormatterForField(agg.params.field).toJSON()
: { id: undefined, params: undefined };
return {
id: 'range',
params: {

View file

@ -82,7 +82,9 @@ export const getTermsBucketAgg = () =>
return agg.getFieldDisplayName() + ': ' + params.order.text;
},
getSerializedFormat(agg) {
const format = agg.params.field ? agg.params.field.format.toJSON() : {};
const format = agg.params.field
? agg.aggConfigs.indexPattern.getFormatterForField(agg.params.field).toJSON()
: { id: undefined, params: undefined };
return {
id: 'terms',
params: {

View file

@ -66,9 +66,6 @@ describe('parent pipeline aggs', function () {
) => {
const field = {
name: 'field',
format: {
toJSON: () => ({ id: 'bytes' }),
},
};
const indexPattern = {
id: '1234',
@ -77,6 +74,9 @@ describe('parent pipeline aggs', function () {
getByName: () => field,
filter: () => [field],
},
getFormatterForField: () => ({
toJSON: () => ({ id: 'bytes' }),
}),
} as any;
const aggConfigs = new AggConfigs(

View file

@ -72,6 +72,9 @@ describe('sibling pipeline aggs', () => {
getByName: () => field,
filter: () => [field],
},
getFormatterForField: () => ({
toJSON: () => ({ id: 'bytes' }),
}),
} as any;
const aggConfigs = new AggConfigs(

View file

@ -30,11 +30,7 @@ import { ValueClickContext } from '../../../../embeddable/public';
const mockField = {
name: 'bytes',
indexPattern: {
id: 'logstash-*',
},
filterable: true,
format: new fieldFormats.BytesFormat({}, (() => {}) as FieldFormatsGetConfigFn),
};
describe('createFiltersFromValueClick', () => {
@ -81,6 +77,8 @@ describe('createFiltersFromValueClick', () => {
getByName: () => mockField,
filter: () => [mockField],
},
getFormatterForField: () =>
new fieldFormats.BytesFormat({}, (() => {}) as FieldFormatsGetConfigFn),
}),
} as unknown) as IndexPatternsContract);
});

View file

@ -262,7 +262,7 @@ export {
UI_SETTINGS,
TypeMeta as IndexPatternTypeMeta,
AggregationRestrictions as IndexPatternAggRestrictions,
FieldList,
fieldList,
} from '../common';
/*

View file

@ -604,46 +604,11 @@ export type FieldFormatsContentType = 'html' | 'text';
// @public (undocumented)
export type FieldFormatsGetConfigFn = GetConfigFn;
// Warning: (ae-missing-release-tag) "FieldList" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// Warning: (ae-forgotten-export) The symbol "FieldSpec" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "fieldList" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export class FieldList extends Array<IndexPatternField> implements IIndexPatternFieldList {
// Warning: (ae-forgotten-export) The symbol "FieldSpec" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "OnNotification" needs to be exported by the entry point index.d.ts
constructor(indexPattern: IndexPattern, specs?: FieldSpec[], shortDotsEnable?: boolean, onNotification?: OnNotification);
// (undocumented)
readonly add: (field: FieldSpec) => void;
// (undocumented)
readonly getAll: () => IndexPatternField[];
// (undocumented)
readonly getByName: (name: IndexPatternField['name']) => IndexPatternField | undefined;
// (undocumented)
readonly getByType: (type: IndexPatternField['type']) => any[];
// (undocumented)
readonly remove: (field: IFieldType) => void;
// (undocumented)
readonly removeAll: () => void;
// (undocumented)
readonly replaceAll: (specs: FieldSpec[]) => void;
// (undocumented)
readonly toSpec: () => {
count: number;
script: string | undefined;
lang: string | undefined;
conflictDescriptions: Record<string, string[]> | undefined;
name: string;
type: string;
esTypes: string[] | undefined;
scripted: boolean;
searchable: boolean;
aggregatable: boolean;
readFromDocValues: boolean;
subType: import("../types").IFieldSubType | undefined;
format: any;
}[];
// (undocumented)
readonly update: (field: FieldSpec) => void;
}
export const fieldList: (specs?: FieldSpec[], shortDotsEnable?: boolean) => IIndexPatternFieldList;
// @public (undocumented)
export interface FieldMappingSpec {
@ -868,7 +833,9 @@ export interface IFieldType {
// (undocumented)
subType?: IFieldSubType;
// (undocumented)
toSpec?: () => FieldSpec;
toSpec?: (options?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}) => FieldSpec;
// (undocumented)
type: string;
// (undocumented)
@ -919,6 +886,10 @@ export interface IIndexPatternFieldList extends Array<IndexPatternField> {
// (undocumented)
replaceAll(specs: FieldSpec[]): void;
// (undocumented)
toSpec(options?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}): FieldSpec[];
// (undocumented)
update(field: FieldSpec): void;
}
@ -1100,7 +1071,7 @@ export interface IndexPatternAttributes {
//
// @public (undocumented)
export class IndexPatternField implements IFieldType {
constructor(indexPattern: IndexPattern, spec: FieldSpec, displayName: string, onNotification: OnNotification);
constructor(spec: FieldSpec, displayName: string);
// (undocumented)
get aggregatable(): boolean;
// (undocumented)
@ -1116,10 +1087,6 @@ export class IndexPatternField implements IFieldType {
// (undocumented)
get filterable(): boolean;
// (undocumented)
get format(): FieldFormat;
// (undocumented)
readonly indexPattern: IndexPattern;
// (undocumented)
get lang(): string | undefined;
set lang(lang: string | undefined);
// (undocumented)
@ -1155,7 +1122,9 @@ export class IndexPatternField implements IFieldType {
subType: import("../types").IFieldSubType | undefined;
};
// (undocumented)
toSpec(): {
toSpec({ getFormatterForField, }?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}): {
count: number;
script: string | undefined;
lang: string | undefined;
@ -1168,7 +1137,10 @@ export class IndexPatternField implements IFieldType {
aggregatable: boolean;
readFromDocValues: boolean;
subType: import("../types").IFieldSubType | undefined;
format: any;
format: {
id: any;
params: any;
} | undefined;
};
// (undocumented)
get type(): string;

View file

@ -52,6 +52,7 @@ describe('createFilter', () => {
getByName: () => field,
filter: () => [field],
},
getFormatterForField: () => new BytesFormat({}, (() => {}) as FieldFormatsGetConfigFn),
} as any;
return new AggConfigs(

View file

@ -565,7 +565,9 @@ export interface IFieldType {
// Warning: (ae-forgotten-export) The symbol "FieldSpec" needs to be exported by the entry point index.d.ts
//
// (undocumented)
toSpec?: () => FieldSpec;
toSpec?: (options?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}) => FieldSpec;
// (undocumented)
type: string;
// (undocumented)
@ -1063,6 +1065,7 @@ export function usageProvider(core: CoreSetup_2): SearchUsage;
// Warnings were encountered during analysis:
//
// src/plugins/data/common/index_patterns/fields/types.ts:41:25 - (ae-forgotten-export) The symbol "IndexPattern" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:40:23 - (ae-forgotten-export) The symbol "buildCustomFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:40:23 - (ae-forgotten-export) The symbol "buildFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/server/index.ts:71:21 - (ae-forgotten-export) The symbol "getEsQueryConfig" needs to be exported by the entry point index.d.ts

View file

@ -62,7 +62,6 @@ function getComponent(selected = false, showDetails = false, useShortDots = fals
);
const field = new IndexPatternField(
indexPattern,
{
name: 'bytes',
type: 'number',
@ -73,8 +72,7 @@ function getComponent(selected = false, showDetails = false, useShortDots = fals
aggregatable: true,
readFromDocValues: true,
},
'bytes',
() => {}
'bytes'
);
const props = {

View file

@ -111,8 +111,8 @@ export function DiscoverSidebar({
);
const getDetailsByField = useCallback(
(ipField: IndexPatternField) => getDetails(ipField, hits, columns),
[hits, columns]
(ipField: IndexPatternField) => getDetails(ipField, hits, columns, selectedIndexPattern),
[hits, columns, selectedIndexPattern]
);
const popularLimit = services.uiSettings.get(FIELDS_LIMIT_SETTING);

View file

@ -20,9 +20,9 @@
import _ from 'lodash';
import { i18n } from '@kbn/i18n';
function getFieldValues(hits, field) {
function getFieldValues(hits, field, indexPattern) {
const name = field.name;
const flattenHit = field.indexPattern.flattenHit;
const flattenHit = indexPattern.flattenHit;
return _.map(hits, function (hit) {
return flattenHit(hit)[name];
});
@ -49,7 +49,7 @@ function getFieldValueCounts(params) {
};
}
const allValues = getFieldValues(params.hits, params.field);
const allValues = getFieldValues(params.hits, params.field, params.indexPattern);
let counts;
const missing = _countMissing(allValues);

View file

@ -148,7 +148,8 @@ describe('fieldCalculator', function () {
it('Should return an array of values for _source fields', function () {
const extensions = fieldCalculator.getFieldValues(
hits,
indexPattern.fields.getByName('extension')
indexPattern.fields.getByName('extension'),
indexPattern
);
expect(extensions).toBeInstanceOf(Array);
expect(
@ -160,7 +161,11 @@ describe('fieldCalculator', function () {
});
it('Should return an array of values for core meta fields', function () {
const types = fieldCalculator.getFieldValues(hits, indexPattern.fields.getByName('_type'));
const types = fieldCalculator.getFieldValues(
hits,
indexPattern.fields.getByName('_type'),
indexPattern
);
expect(types).toBeInstanceOf(Array);
expect(
_.filter(types, function (v) {
@ -172,12 +177,13 @@ describe('fieldCalculator', function () {
});
describe('getFieldValueCounts', function () {
let params: { hits: any; field: any; count: number };
let params: { hits: any; field: any; count: number; indexPattern: IndexPattern };
beforeEach(function () {
params = {
hits: _.cloneDeep(realHits),
field: indexPattern.fields.getByName('extension'),
count: 3,
indexPattern,
};
});

View file

@ -19,17 +19,19 @@
// @ts-ignore
import { fieldCalculator } from './field_calculator';
import { IndexPatternField } from '../../../../../../data/public';
import { IndexPattern, IndexPatternField } from '../../../../../../data/public';
export function getDetails(
field: IndexPatternField,
hits: Array<Record<string, unknown>>,
columns: string[]
columns: string[],
indexPattern: IndexPattern
) {
const details = {
...fieldCalculator.getFieldValueCounts({
hits,
field,
indexPattern,
count: 5,
grouped: false,
}),
@ -37,7 +39,7 @@ export function getDetails(
};
if (details.buckets) {
for (const bucket of details.buckets) {
bucket.display = field.format.convert(bucket.value);
bucket.display = indexPattern.getFormatterForField(field).convert(bucket.value);
}
}
return details;

View file

@ -31,6 +31,7 @@ export function getIndexPatternFieldList(
difference(fieldNamesInDocs, fieldNamesInIndexPattern).forEach((unknownFieldName) => {
unknownTypes.push({
displayName: String(unknownFieldName),
name: String(unknownFieldName),
type: 'unknown',
} as IndexPatternField);

View file

@ -15,13 +15,10 @@ exports[`IndexedFieldsTable should filter based on the query bar 1`] = `
"displayName": "Elastic",
"excluded": false,
"format": undefined,
"indexPattern": Object {
"getNonScriptedFields": [Function],
},
"info": Array [],
"name": "Elastic",
"searchable": true,
"type": "name",
"type": "string",
},
]
}
@ -44,9 +41,6 @@ exports[`IndexedFieldsTable should filter based on the type filter 1`] = `
"displayName": "timestamp",
"excluded": false,
"format": undefined,
"indexPattern": Object {
"getNonScriptedFields": [Function],
},
"info": Array [],
"name": "timestamp",
"type": "date",
@ -72,21 +66,15 @@ exports[`IndexedFieldsTable should render normally 1`] = `
"displayName": "Elastic",
"excluded": false,
"format": undefined,
"indexPattern": Object {
"getNonScriptedFields": [Function],
},
"info": Array [],
"name": "Elastic",
"searchable": true,
"type": "name",
"type": "string",
},
Object {
"displayName": "timestamp",
"excluded": false,
"format": undefined,
"indexPattern": Object {
"getNonScriptedFields": [Function],
},
"info": Array [],
"name": "timestamp",
"type": "date",
@ -95,9 +83,6 @@ exports[`IndexedFieldsTable should render normally 1`] = `
"displayName": "conflictingField",
"excluded": false,
"format": undefined,
"indexPattern": Object {
"getNonScriptedFields": [Function],
},
"info": Array [],
"name": "conflictingField",
"type": "conflict",

View file

@ -19,7 +19,7 @@
import React from 'react';
import { shallow } from 'enzyme';
import { IndexPatternField, IIndexPattern, IndexPattern } from 'src/plugins/data/public';
import { IndexPatternField, IIndexPattern } from 'src/plugins/data/public';
import { IndexedFieldsTable } from './indexed_fields_table';
jest.mock('@elastic/eui', () => ({
@ -47,10 +47,8 @@ const indexPattern = ({
const mockFieldToIndexPatternField = (spec: Record<string, string | boolean | undefined>) => {
return new IndexPatternField(
indexPattern as IndexPattern,
(spec as unknown) as IndexPatternField['spec'],
spec.displayName as string,
() => {}
spec.displayName as string
);
};
@ -59,7 +57,7 @@ const fields = [
name: 'Elastic',
displayName: 'Elastic',
searchable: true,
type: 'name',
type: 'string',
},
{ name: 'timestamp', displayName: 'timestamp', type: 'date' },
{ name: 'conflictingField', displayName: 'conflictingField', type: 'conflict' },

View file

@ -77,7 +77,6 @@ export class IndexedFieldsTable extends Component<
return {
...field.spec,
displayName: field.displayName,
indexPattern: field.indexPattern,
format: getFieldFormat(indexPattern, field.name),
excluded: fieldWildcardMatch ? fieldWildcardMatch(field.name) : false,
info: helpers.getFieldInfo && helpers.getFieldInfo(indexPattern, field),

View file

@ -176,7 +176,7 @@ export function Tabs({ indexPattern, fields, history, location }: TabsProps) {
indexedFieldTypeFilter={indexedFieldTypeFilter}
helpers={{
redirectToRoute: (field: IndexPatternField) => {
history.push(getPath(field));
history.push(getPath(field, indexPattern));
},
getFieldInfo: indexPatternManagementStart.list.getFieldInfo,
}}
@ -195,7 +195,7 @@ export function Tabs({ indexPattern, fields, history, location }: TabsProps) {
scriptedFieldLanguageFilter={scriptedFieldLanguageFilter}
helpers={{
redirectToRoute: (field: IndexPatternField) => {
history.push(getPath(field));
history.push(getPath(field, indexPattern));
},
}}
onRemoveField={refreshFilters}

View file

@ -116,8 +116,8 @@ export function getTabs(
return tabs;
}
export function getPath(field: IndexPatternField) {
return `/patterns/${field.indexPattern?.id}/field/${field.name}`;
export function getPath(field: IndexPatternField, indexPattern: IndexPattern) {
return `/patterns/${indexPattern?.id}/field/${field.name}`;
}
const allTypesDropDown = i18n.translate(

View file

@ -138,12 +138,12 @@ describe('FieldEditor', () => {
name: 'test',
script: 'doc.test.value',
};
fieldList.push(testField as IndexPatternField);
fieldList.push((testField as unknown) as IndexPatternField);
indexPattern.fields.getByName = (name) => {
const flds = {
[testField.name]: testField,
};
return flds[name] as IndexPatternField;
return (flds[name] as unknown) as IndexPatternField;
};
const component = createComponentWithContext<FieldEdiorProps>(
@ -173,7 +173,7 @@ describe('FieldEditor', () => {
const flds = {
[testField.name]: testField,
};
return flds[name] as IndexPatternField;
return (flds[name] as unknown) as IndexPatternField;
};
const component = createComponentWithContext<FieldEdiorProps>(

View file

@ -81,9 +81,10 @@ export abstract class Control<FilterManager extends BaseFilterManager> {
abstract destroy(): void;
format = (value: any) => {
const indexPattern = this.filterManager.getIndexPattern();
const field = this.filterManager.getField();
if (field?.format?.convert) {
return field.format.convert(value);
if (field) {
return indexPattern.getFormatterForField(field).convert(value);
}
return value;

View file

@ -22,7 +22,7 @@ import sinon from 'sinon';
// because it is one of the few places that we need to access the IndexPattern class itself, rather
// than just the type. Doing this as a temporary measure; it will be left behind when migrating to NP.
import { IndexPattern, indexPatterns, KBN_FIELD_TYPES, FieldList } from '../../plugins/data/public';
import { IndexPattern, indexPatterns, KBN_FIELD_TYPES, fieldList } from '../../plugins/data/public';
import { setFieldFormats } from '../../plugins/data/public/services';
@ -64,7 +64,7 @@ export default function StubIndexPattern(pattern, getConfig, timeField, fields,
});
this._reindexFields = function () {
this.fields = new FieldList(this, this.fields || fields, false);
this.fields = fieldList(this.fields || fields, false);
};
this.stubSetFieldFormat = function (fieldName, id, params) {

View file

@ -281,7 +281,7 @@ export class AbstractESSource extends AbstractVectorSource {
return null;
}
return fieldFromIndexPattern.format.getConverterFor('text');
return indexPattern.getFormatterForField(fieldFromIndexPattern).getConverterFor('text');
}
async loadStylePropsMeta(

View file

@ -10,8 +10,8 @@ import { IField } from '../fields/field';
import {
esFilters,
Filter,
IFieldType,
IndexPattern,
IndexPatternField,
} from '../../../../../../src/plugins/data/public';
export class ESTooltipProperty implements ITooltipProperty {
@ -37,7 +37,7 @@ export class ESTooltipProperty implements ITooltipProperty {
return this._tooltipProperty.getRawValue();
}
_getIndexPatternField(): IFieldType | undefined {
_getIndexPatternField(): IndexPatternField | undefined {
return this._indexPattern.fields.getByName(this._field.getRootName());
}
@ -56,10 +56,11 @@ export class ESTooltipProperty implements ITooltipProperty {
}
}
const htmlConverter = indexPatternField.format.getConverterFor('html');
const formatter = this._indexPattern.getFormatterForField(indexPatternField);
const htmlConverter = formatter.getConverterFor('html');
return htmlConverter
? htmlConverter(this.getRawValue())
: indexPatternField.format.convert(this.getRawValue());
: formatter.convert(this.getRawValue());
}
isFilterable(): boolean {

View file

@ -77,7 +77,7 @@ class FieldFormatService {
const fieldList = fullIndexPattern.fields;
const field = fieldList.getByName(fieldName);
if (field !== undefined) {
fieldFormat = field.format;
fieldFormat = fullIndexPattern.getFormatterForField(field);
}
}
@ -104,7 +104,9 @@ class FieldFormatService {
if (dtr.field_name !== undefined && esAgg !== 'cardinality') {
const field = fieldList.getByName(dtr.field_name);
if (field !== undefined) {
formatsByDetector[dtr.detector_index!] = field.format;
formatsByDetector[dtr.detector_index!] = indexPatternData.getFormatterForField(
field
);
}
}
});

View file

@ -140,7 +140,11 @@ describe('helpers', () => {
filterManager: mockFilterManager,
query: mockQueryBarWithFilters.query,
savedId: mockQueryBarWithFilters.saved_id,
indexPatterns: { fields: [{ name: 'test name', type: 'test type' }], title: 'test title' },
indexPatterns: {
fields: [{ name: 'event.category', type: 'test type' }],
title: 'test title',
getFormatterForField: () => ({ convert: (val: unknown) => val }),
},
});
const wrapper = shallow<React.ReactElement>(result[0].description as React.ReactElement);
const filterLabelComponent = wrapper.find(esFilters.FilterLabel).at(0);