mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[data views] Use map object for field attributes (#193760)
## Summary Use map object for field attributes --------- Co-authored-by: Davis McPhee <davismcphee@hotmail.com>
This commit is contained in:
parent
9357d44372
commit
760455a0ff
6 changed files with 50 additions and 40 deletions
|
@ -13,7 +13,7 @@ import type {
|
|||
SerializedFieldFormat,
|
||||
} from '@kbn/field-formats-plugin/common';
|
||||
import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '@kbn/field-types';
|
||||
import { cloneDeep, merge } from 'lodash';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import type { DataViewFieldBase } from '@kbn/es-query';
|
||||
import type {
|
||||
DataViewSpec,
|
||||
|
@ -161,7 +161,7 @@ export abstract class AbstractDataView {
|
|||
}
|
||||
return acc;
|
||||
}, {} as Record<string, FieldAttrSet>)
|
||||
: [];
|
||||
: {};
|
||||
|
||||
this.allowNoIndex = spec?.allowNoIndex || false;
|
||||
|
||||
|
@ -191,7 +191,7 @@ export abstract class AbstractDataView {
|
|||
this.sourceFilters = [...(spec.sourceFilters || [])];
|
||||
this.type = spec.type;
|
||||
this.typeMeta = spec.typeMeta;
|
||||
this.fieldAttrs = cloneDeep(merge({}, extractedFieldAttrs, spec.fieldAttrs)) || {};
|
||||
this.fieldAttrs = new Map(Object.entries({ ...extractedFieldAttrs, ...spec.fieldAttrs }));
|
||||
this.runtimeFieldMap = cloneDeep(spec.runtimeFieldMap) || {};
|
||||
this.namespaces = spec.namespaces || [];
|
||||
this.name = spec.name || '';
|
||||
|
@ -300,10 +300,8 @@ export abstract class AbstractDataView {
|
|||
attrName: K,
|
||||
value: FieldAttrSet[K]
|
||||
) {
|
||||
if (!this.fieldAttrs[fieldName]) {
|
||||
this.fieldAttrs[fieldName] = {} as FieldAttrSet;
|
||||
}
|
||||
this.fieldAttrs[fieldName][attrName] = value;
|
||||
const fieldAttrs = this.fieldAttrs.get(fieldName) || {};
|
||||
this.fieldAttrs.set(fieldName, { ...fieldAttrs, [attrName]: value });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -368,7 +366,7 @@ export abstract class AbstractDataView {
|
|||
const stringifyOrUndefined = (obj: any) => (obj ? JSON.stringify(obj) : undefined);
|
||||
|
||||
return {
|
||||
fieldAttrs: stringifyOrUndefined(this.fieldAttrs),
|
||||
fieldAttrs: stringifyOrUndefined(Object.fromEntries(this.fieldAttrs.entries())),
|
||||
title: this.getIndexPattern(),
|
||||
timeFieldName: this.timeFieldName,
|
||||
sourceFilters: stringifyOrUndefined(this.sourceFilters),
|
||||
|
@ -385,7 +383,7 @@ export abstract class AbstractDataView {
|
|||
|
||||
protected toSpecShared(includeFields = true): DataViewSpec {
|
||||
// if fields aren't included, don't include count
|
||||
const fieldAttrs = cloneDeep(this.fieldAttrs);
|
||||
const fieldAttrs = Object.fromEntries(this.fieldAttrs.entries());
|
||||
if (!includeFields) {
|
||||
Object.keys(fieldAttrs).forEach((key) => {
|
||||
delete fieldAttrs[key].count;
|
||||
|
@ -546,5 +544,8 @@ export abstract class AbstractDataView {
|
|||
this.runtimeFieldMap[name] = removeFieldAttrs(runtimeField);
|
||||
}
|
||||
|
||||
getFieldAttrs = () => cloneDeep(this.fieldAttrs);
|
||||
getFieldAttrs = () => {
|
||||
const clonedFieldAttrs = cloneDeep(Object.fromEntries(this.fieldAttrs.entries()));
|
||||
return new Map(Object.entries(clonedFieldAttrs));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -523,7 +523,7 @@ describe('IndexPattern', () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
expect(dataView.getFieldAttrs()).toMatchInlineSnapshot(`
|
||||
expect(Object.fromEntries(dataView.getFieldAttrs().entries())).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"test1": Object {
|
||||
"count": 5,
|
||||
|
@ -555,7 +555,7 @@ describe('IndexPattern', () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
expect(dataView.getFieldAttrs()).toMatchInlineSnapshot(`
|
||||
expect(Object.fromEntries(dataView.getFieldAttrs().entries())).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"test1": Object {
|
||||
"count": 2,
|
||||
|
|
|
@ -132,11 +132,12 @@ export class DataViewLazy extends AbstractDataView {
|
|||
return col;
|
||||
}
|
||||
if (!cachedField) {
|
||||
const fldAttrs = this.fieldAttrs.get(field.name) || {};
|
||||
cachedField = new DataViewField({
|
||||
...field,
|
||||
count: this.fieldAttrs?.[field.name]?.count,
|
||||
customLabel: this.fieldAttrs?.[field.name]?.customLabel,
|
||||
customDescription: this.fieldAttrs?.[field.name]?.customDescription,
|
||||
count: fldAttrs.count,
|
||||
customLabel: fldAttrs.customLabel,
|
||||
customDescription: fldAttrs.customDescription,
|
||||
shortDotsEnable: this.shortDotsEnable,
|
||||
});
|
||||
this.fieldCache.set(field.name, cachedField);
|
||||
|
@ -338,6 +339,7 @@ export class DataViewLazy extends AbstractDataView {
|
|||
runtimeField: RuntimeFieldSpec,
|
||||
parentName?: string
|
||||
) => {
|
||||
const fldAttrs = this.fieldAttrs.get(name) || {};
|
||||
spec[name] = {
|
||||
name,
|
||||
type: castEsToKbnFieldTypeName(fieldType),
|
||||
|
@ -346,9 +348,9 @@ export class DataViewLazy extends AbstractDataView {
|
|||
aggregatable: true,
|
||||
searchable: true,
|
||||
readFromDocValues: false,
|
||||
customLabel: this.fieldAttrs?.[name]?.customLabel,
|
||||
customDescription: this.fieldAttrs?.[name]?.customDescription,
|
||||
count: this.fieldAttrs?.[name]?.count,
|
||||
customLabel: fldAttrs.customLabel,
|
||||
customDescription: fldAttrs.customDescription,
|
||||
count: fldAttrs.count,
|
||||
};
|
||||
|
||||
if (parentName) {
|
||||
|
@ -391,14 +393,15 @@ export class DataViewLazy extends AbstractDataView {
|
|||
if (fld && !fld.scripted && fld.isMapped) {
|
||||
this.fieldCache.delete(field.name);
|
||||
}
|
||||
const fldAttrs = this.fieldAttrs.get(field.name) || {};
|
||||
fld = new DataViewField({
|
||||
...field,
|
||||
scripted: true,
|
||||
searchable: true,
|
||||
aggregatable: true,
|
||||
count: this.fieldAttrs?.[field.name]?.count,
|
||||
customLabel: this.fieldAttrs?.[field.name]?.customLabel,
|
||||
customDescription: this.fieldAttrs?.[field.name]?.customDescription,
|
||||
count: fldAttrs.count,
|
||||
customLabel: fldAttrs.customLabel,
|
||||
customDescription: fldAttrs.customDescription,
|
||||
});
|
||||
this.fieldCache.set(field.name, fld);
|
||||
dataViewFields[field.name] = fld;
|
||||
|
@ -437,11 +440,12 @@ export class DataViewLazy extends AbstractDataView {
|
|||
fld.spec.runtimeField = undefined; // unset if it was a runtime field but now mapped
|
||||
fld.spec.isMapped = true;
|
||||
} else {
|
||||
const fldAttrs = this.fieldAttrs.get(field.name) || {};
|
||||
fld = new DataViewField({
|
||||
...field,
|
||||
count: this.fieldAttrs?.[field.name]?.count,
|
||||
customLabel: this.fieldAttrs?.[field.name]?.customLabel,
|
||||
customDescription: this.fieldAttrs?.[field.name]?.customDescription,
|
||||
count: fldAttrs.count,
|
||||
customLabel: fldAttrs.customLabel,
|
||||
customDescription: fldAttrs.customDescription,
|
||||
shortDotsEnable: this.shortDotsEnable,
|
||||
});
|
||||
this.fieldCache.set(field.name, fld);
|
||||
|
|
|
@ -28,6 +28,7 @@ import {
|
|||
DataViewSpec,
|
||||
DataViewAttributes,
|
||||
FieldAttrs,
|
||||
FieldAttrsAsObject,
|
||||
FieldSpec,
|
||||
DataViewFieldMap,
|
||||
TypeMeta,
|
||||
|
@ -187,7 +188,7 @@ export interface DataViewsServicePublicMethods {
|
|||
* @params fieldAttrs - Field attributes, map by name
|
||||
* @returns Field map by name
|
||||
*/
|
||||
fieldArrayToMap: (fields: FieldSpec[], fieldAttrs?: FieldAttrs | undefined) => DataViewFieldMap;
|
||||
fieldArrayToMap: (fields: FieldSpec[], fieldAttrs?: FieldAttrsAsObject) => DataViewFieldMap;
|
||||
/**
|
||||
* Search for data views based on title
|
||||
* @param search - Search string
|
||||
|
@ -658,7 +659,8 @@ export class DataViewsService {
|
|||
const scripted = this.scriptedFieldsEnabled
|
||||
? indexPattern.getScriptedFields().map((field) => field.spec)
|
||||
: [];
|
||||
const fieldAttrs = indexPattern.getFieldAttrs();
|
||||
|
||||
const fieldAttrs = Object.fromEntries(indexPattern.getFieldAttrs().entries());
|
||||
const fieldsWithSavedAttrs = Object.values(
|
||||
this.fieldArrayToMap([...fields, ...scripted], fieldAttrs)
|
||||
);
|
||||
|
@ -721,7 +723,7 @@ export class DataViewsService {
|
|||
id: string,
|
||||
title: string,
|
||||
options: GetFieldsOptions,
|
||||
fieldAttrs: FieldAttrs = {},
|
||||
fieldAttrs: FieldAttrsAsObject = {},
|
||||
displayErrors: boolean = true
|
||||
) => {
|
||||
const fieldsAsArr = Object.values(fields);
|
||||
|
@ -772,7 +774,7 @@ export class DataViewsService {
|
|||
* @param fieldAttrs: FieldAttrs
|
||||
* @returns Record<string, FieldSpec>
|
||||
*/
|
||||
fieldArrayToMap = (fields: FieldSpec[], fieldAttrs?: FieldAttrs) =>
|
||||
fieldArrayToMap = (fields: FieldSpec[], fieldAttrs?: FieldAttrsAsObject) =>
|
||||
fields.reduce<DataViewFieldMap>((collector, field) => {
|
||||
collector[field.name] = {
|
||||
...field,
|
||||
|
@ -814,7 +816,7 @@ export class DataViewsService {
|
|||
const parsedTypeMeta = typeMeta ? JSON.parse(typeMeta) : undefined;
|
||||
const parsedFieldFormatMap = fieldFormatMap ? JSON.parse(fieldFormatMap) : {};
|
||||
const parsedFields: FieldSpec[] = fields ? JSON.parse(fields) : [];
|
||||
const parsedFieldAttrs: FieldAttrs = fieldAttrs ? JSON.parse(fieldAttrs) : {};
|
||||
const parsedFieldAttrs: FieldAttrsAsObject = fieldAttrs ? JSON.parse(fieldAttrs) : {};
|
||||
const parsedRuntimeFieldMap: Record<string, RuntimeField> = runtimeFieldMap
|
||||
? JSON.parse(runtimeFieldMap)
|
||||
: {};
|
||||
|
@ -877,7 +879,10 @@ export class DataViewsService {
|
|||
displayErrors
|
||||
);
|
||||
|
||||
const runtimeFieldSpecs = this.getRuntimeFields(runtimeFieldMap, spec.fieldAttrs);
|
||||
const runtimeFieldSpecs = this.getRuntimeFields(
|
||||
runtimeFieldMap,
|
||||
new Map(Object.entries(spec.fieldAttrs || {}))
|
||||
);
|
||||
// mapped fields overwrite runtime fields
|
||||
return { fields: { ...runtimeFieldSpecs, ...fields }, indices: indices || [], etag };
|
||||
};
|
||||
|
@ -946,7 +951,7 @@ export class DataViewsService {
|
|||
|
||||
private getRuntimeFields = (
|
||||
runtimeFieldMap: Record<string, RuntimeFieldSpec> | undefined = {},
|
||||
fieldAttrs: FieldAttrs | undefined = {}
|
||||
fieldAttrs: FieldAttrs | undefined = new Map()
|
||||
) => {
|
||||
const spec: DataViewFieldMap = {};
|
||||
|
||||
|
@ -956,6 +961,7 @@ export class DataViewsService {
|
|||
runtimeField: RuntimeFieldSpec,
|
||||
parentName?: string
|
||||
) => {
|
||||
const fldAttrs = fieldAttrs.get(name) || {};
|
||||
spec[name] = {
|
||||
name,
|
||||
type: castEsToKbnFieldTypeName(fieldType),
|
||||
|
@ -964,9 +970,9 @@ export class DataViewsService {
|
|||
aggregatable: true,
|
||||
searchable: true,
|
||||
readFromDocValues: false,
|
||||
customLabel: fieldAttrs?.[name]?.customLabel,
|
||||
customDescription: fieldAttrs?.[name]?.customDescription,
|
||||
count: fieldAttrs?.[name]?.count,
|
||||
customLabel: fldAttrs.customLabel,
|
||||
customDescription: fldAttrs.customDescription,
|
||||
count: fldAttrs.count,
|
||||
};
|
||||
|
||||
if (parentName) {
|
||||
|
|
|
@ -173,10 +173,7 @@ export interface DataViewAttributes {
|
|||
* @public
|
||||
* Storage of field attributes. Necessary since the field list isn't saved.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||
export type FieldAttrs = {
|
||||
[key: string]: FieldAttrSet;
|
||||
};
|
||||
export type FieldAttrs = Map<string, FieldAttrSet>;
|
||||
|
||||
/**
|
||||
* Field attributes that are stored on the data view
|
||||
|
@ -198,6 +195,8 @@ export type FieldAttrSet = {
|
|||
count?: number;
|
||||
};
|
||||
|
||||
export type FieldAttrsAsObject = Record<string, FieldAttrSet>;
|
||||
|
||||
/**
|
||||
* Handler for data view notifications
|
||||
* @public
|
||||
|
@ -537,7 +536,7 @@ export type DataViewSpec = {
|
|||
/**
|
||||
* Map of field attributes by field name, currently customName and count
|
||||
*/
|
||||
fieldAttrs?: FieldAttrs;
|
||||
fieldAttrs?: FieldAttrsAsObject;
|
||||
/**
|
||||
* Determines whether failure to load field list should be reported as error
|
||||
*/
|
||||
|
|
|
@ -255,7 +255,7 @@ describe('LogViewsClient class', () => {
|
|||
"deleteFieldFormat": [Function],
|
||||
"deleteScriptedFieldInternal": [Function],
|
||||
"etag": undefined,
|
||||
"fieldAttrs": Object {},
|
||||
"fieldAttrs": Map {},
|
||||
"fieldFormatMap": Object {},
|
||||
"fieldFormats": Object {
|
||||
"deserialize": [MockFunction],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue