Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into kbn-XXX-so-migrat…
Browse files Browse the repository at this point in the history
…ion-fn-generics
  • Loading branch information
pgayvallet committed Apr 21, 2020
2 parents 2504a55 + 46f6f87 commit a0ad3fb
Show file tree
Hide file tree
Showing 13 changed files with 310 additions and 25 deletions.
2 changes: 2 additions & 0 deletions src/plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ import {
convertIPRangeToString,
intervalOptions, // only used in Discover
isDateHistogramBucketAggConfig,
isNumberType,
isStringType,
isType,
parentPipelineType,
Expand Down Expand Up @@ -392,6 +393,7 @@ export const search = {
InvalidEsCalendarIntervalError,
InvalidEsIntervalFormatError,
isDateHistogramBucketAggConfig,
isNumberType,
isStringType,
isType,
isValidEsInterval,
Expand Down
33 changes: 17 additions & 16 deletions src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1545,8 +1545,9 @@ export const search: {
InvalidEsCalendarIntervalError: typeof InvalidEsCalendarIntervalError;
InvalidEsIntervalFormatError: typeof InvalidEsIntervalFormatError;
isDateHistogramBucketAggConfig: typeof isDateHistogramBucketAggConfig;
isNumberType: (agg: import("./search").AggConfig) => boolean;
isStringType: (agg: import("./search").AggConfig) => boolean;
isType: (type: string) => (agg: import("./search").AggConfig) => boolean;
isType: (...types: string[]) => (agg: import("./search").AggConfig) => boolean;
isValidEsInterval: typeof isValidEsInterval;
isValidInterval: typeof isValidInterval;
parentPipelineType: string;
Expand Down Expand Up @@ -1874,21 +1875,21 @@ export type TSearchStrategyProvider<T extends TStrategyTypes> = (context: ISearc
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "getRoutes" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:387:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "convertDateRangeToString" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:399:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:404:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:405:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:408:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:409:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:383:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:383:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:383:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:383:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "convertDateRangeToString" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:391:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:406:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:407:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:410:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:414:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:33:33 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:37:1 - (ae-forgotten-export) The symbol "QueryStateChange" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:52:5 - (ae-forgotten-export) The symbol "createFiltersFromEvent" needs to be exported by the entry point index.d.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,22 @@ import { isString, isObject } from 'lodash';
import { IBucketAggConfig, BucketAggType, BucketAggParam } from './bucket_agg_type';
import { IAggConfig } from '../agg_config';

export const isType = (type: string) => {
export const isType = (...types: string[]) => {
return (agg: IAggConfig): boolean => {
const field = agg.params.field;

return field && field.type === type;
return types.some(type => field && field.type === type);
};
};

export const isNumberType = isType('number');
export const isStringType = isType('string');
export const isStringOrNumberType = isType('string', 'number');

export const migrateIncludeExcludeFormat = {
serialize(this: BucketAggParam<IBucketAggConfig>, value: any, agg: IBucketAggConfig) {
if (this.shouldShow && !this.shouldShow(agg)) return;
if (!value || isString(value)) return value;
if (!value || isString(value) || Array.isArray(value)) return value;
else return value.pattern;
},
write(
Expand All @@ -44,7 +46,12 @@ export const migrateIncludeExcludeFormat = {
) {
const value = aggConfig.getParam(this.name);

if (isObject(value)) {
if (Array.isArray(value) && value.length > 0 && isNumberType(aggConfig)) {
const parsedValue = value.filter((val): val is number => Number.isFinite(val));
if (parsedValue.length) {
output.params[this.name] = parsedValue;
}
} else if (isObject(value)) {
output.params[this.name] = value.pattern;
} else if (value && isStringType(aggConfig)) {
output.params[this.name] = value;
Expand Down
60 changes: 60 additions & 0 deletions src/plugins/data/public/search/aggs/buckets/terms.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,65 @@ describe('Terms Agg', () => {
expect(params.include).toBe('404');
expect(params.exclude).toBe('400');
});

test('accepts string from string field type and writes this value', () => {
const aggConfigs = getAggConfigs({
include: 'include value',
exclude: 'exclude value',
field: {
name: 'string_field',
type: 'string',
},
orderAgg: {
type: 'count',
},
});

const { [BUCKET_TYPES.TERMS]: params } = aggConfigs.aggs[0].toDsl();

expect(params.field).toBe('string_field');
expect(params.include).toBe('include value');
expect(params.exclude).toBe('exclude value');
});

test('accepts empty array from number field type and does not write a value', () => {
const aggConfigs = getAggConfigs({
include: [],
exclude: [],
field: {
name: 'empty_number_field',
type: 'number',
},
orderAgg: {
type: 'count',
},
});

const { [BUCKET_TYPES.TERMS]: params } = aggConfigs.aggs[0].toDsl();

expect(params.field).toBe('empty_number_field');
expect(params.include).toBe(undefined);
expect(params.exclude).toBe(undefined);
});

test('filters array with empty strings from number field type and writes only numbers', () => {
const aggConfigs = getAggConfigs({
include: [1.1, 2, '', 3.33, ''],
exclude: ['', 4, 5.555, '', 6],
field: {
name: 'number_field',
type: 'number',
},
orderAgg: {
type: 'count',
},
});

const { [BUCKET_TYPES.TERMS]: params } = aggConfigs.aggs[0].toDsl();

expect(params.field).toBe('number_field');
expect(params.include).toStrictEqual([1.1, 2, 3.33]);
expect(params.exclude).toStrictEqual([4, 5.555, 6]);
});
});
});
9 changes: 6 additions & 3 deletions src/plugins/data/public/search/aggs/buckets/terms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import { i18n } from '@kbn/i18n';
import { BucketAggType, IBucketAggConfig } from './bucket_agg_type';
import { BUCKET_TYPES } from './bucket_agg_types';
import { createFilterTerms } from './create_filter/terms';
import { isStringType, migrateIncludeExcludeFormat } from './migrate_include_exclude_format';
import {
isStringOrNumberType,
migrateIncludeExcludeFormat,
} from './migrate_include_exclude_format';
import { IAggConfigs } from '../agg_configs';

import { Adapters } from '../../../../../inspector/public';
Expand Down Expand Up @@ -266,7 +269,7 @@ export const getTermsBucketAgg = ({ getInternalStartServices }: TermsBucketAggDe
}),
type: 'string',
advanced: true,
shouldShow: isStringType,
shouldShow: isStringOrNumberType,
...migrateIncludeExcludeFormat,
},
{
Expand All @@ -276,7 +279,7 @@ export const getTermsBucketAgg = ({ getInternalStartServices }: TermsBucketAggDe
}),
type: 'string',
advanced: true,
shouldShow: isStringType,
shouldShow: isStringOrNumberType,
...migrateIncludeExcludeFormat,
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const buckets = {
size: controls.SizeParamEditor,
},
[BUCKET_TYPES.TERMS]: {
include: controls.IncludeExcludeParamEditor,
exclude: controls.IncludeExcludeParamEditor,
orderBy: controls.OrderByParamEditor,
orderAgg: controls.OrderAggParamEditor,
order: wrapWithInlineComp(controls.OrderParamEditor),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function getNextModel(list: NumberRowModel[], range: NumberListRange): NumberRow
};
}

function getInitModelList(list: Array<number | undefined>): NumberRowModel[] {
function getInitModelList(list: Array<number | undefined | ''>): NumberRowModel[] {
return list.length
? list.map(num => ({
value: (num === undefined ? EMPTY_STRING : num) as NumberRowModel['value'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* 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 React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
import { isArray } from 'lodash';
import { EuiButtonEmpty, EuiFlexItem, EuiFormRow, EuiSpacer, htmlIdGenerator } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { EMPTY_STRING, getInitModelList, getRange, parse } from './number_list/utils';
import { NumberRow, NumberRowModel } from './number_list/number_row';
import { AggParamEditorProps } from '../../agg_param_props';

const generateId = htmlIdGenerator();

function SimpleNumberList({
agg,
aggParam,
value,
setValue,
setTouched,
}: AggParamEditorProps<Array<number | ''>>) {
const [numbers, setNumbers] = useState(
getInitModelList(value && isArray(value) ? value : [EMPTY_STRING])
);
const numberRange = useMemo(() => getRange('[-Infinity,Infinity]'), []);

// This useEffect is needed to discard changes, it sets numbers a mapped value if they are different
useEffect(() => {
if (
isArray(value) &&
(value.length !== numbers.length ||
!value.every((numberValue, index) => numberValue === numbers[index].value))
) {
setNumbers(
value.map(numberValue => ({
id: generateId(),
value: numberValue,
isInvalid: false,
}))
);
}
}, [numbers, value]);

const onUpdate = useCallback(
(numberList: NumberRowModel[]) => {
setNumbers(numberList);
setValue(numberList.map(({ value: numberValue }) => numberValue));
},
[setValue]
);

const onChangeValue = useCallback(
(numberField: { id: string; value: string }) => {
onUpdate(
numbers.map(number =>
number.id === numberField.id
? {
id: numberField.id,
value: parse(numberField.value),
isInvalid: false,
}
: number
)
);
},
[numbers, onUpdate]
);

// Add an item to the end of the list
const onAdd = useCallback(() => {
const newArray = [
...numbers,
{
id: generateId(),
value: EMPTY_STRING as '',
isInvalid: false,
},
];
onUpdate(newArray);
}, [numbers, onUpdate]);

const onDelete = useCallback(
(id: string) => onUpdate(numbers.filter(number => number.id !== id)),
[numbers, onUpdate]
);

return (
<EuiFormRow
id={`${aggParam.name}-${agg.id}}`}
label={aggParam.displayName || aggParam.name}
fullWidth={true}
compressed
>
<>
{numbers.map((number, arrayIndex) => (
<Fragment key={number.id}>
<NumberRow
isInvalid={number.isInvalid}
disableDelete={numbers.length === 1}
model={number}
labelledbyId={`${aggParam.name}-${agg.id}-legend`}
range={numberRange}
onDelete={onDelete}
onChange={onChangeValue}
onBlur={setTouched}
autoFocus={numbers.length !== 1 && arrayIndex === numbers.length - 1}
/>
{numbers.length - 1 !== arrayIndex && <EuiSpacer size="s" />}
</Fragment>
))}
<EuiSpacer size="s" />
<EuiFlexItem>
<EuiButtonEmpty iconType="plusInCircleFilled" onClick={onAdd} size="xs">
<FormattedMessage
id="visDefaultEditor.controls.includeExclude.addUnitButtonLabel"
defaultMessage="Add value"
/>
</EuiButtonEmpty>
</EuiFlexItem>
</>
</EuiFormRow>
);
}

export { SimpleNumberList };
Loading

0 comments on commit a0ad3fb

Please sign in to comment.