[ui/public/utils] Move items into agg_types (#52744)

Closes #51855
This commit is contained in:
Alexey Antonov 2019-12-11 21:25:18 +03:00 committed by GitHub
parent 19fec54e0b
commit f2b48910a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 159 additions and 201 deletions

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { CidrMask } from '../../../utils/cidr_mask';
import { CidrMask } from '../lib/cidr_mask';
import { IBucketAggConfig } from '../_bucket_agg_type';
import { IpRangeKey } from '../ip_range';
import { esFilters } from '../../../../../../plugins/data/public';

View file

@ -25,8 +25,6 @@ import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { createFilterDateRange } from './create_filter/date_range';
import { DateRangesParamEditor } from '../../vis/editors/default/controls/date_ranges';
// @ts-ignore
import { dateRange } from '../../utils/date_range';
import {
KBN_FIELD_TYPES,
TEXT_CONTEXT_TYPE,
@ -57,7 +55,7 @@ export const dateRangeBucketAgg = new BucketAggType({
fieldFormats.getDefaultInstance(KBN_FIELD_TYPES.DATE)
);
const DateRangeFormat = FieldFormat.from(function(range: DateRangeKey) {
return dateRange.toString(range, formatter);
return convertDateRangeToString(range, formatter);
});
return new DateRangeFormat();
},
@ -114,3 +112,16 @@ export const dateRangeBucketAgg = new BucketAggType({
},
],
});
export const convertDateRangeToString = (
{ from, to }: DateRangeKey,
format: (val: any) => string
) => {
if (!from) {
return 'Before ' + format(to);
} else if (!to) {
return 'After ' + format(from);
} else {
return format(from) + ' to ' + format(to);
}
};

View file

@ -28,8 +28,7 @@ import { PrecisionParamEditor } from '../../vis/editors/default/controls/precisi
import { AggGroupNames } from '../../vis/editors/default/agg_groups';
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
// @ts-ignore
import { geoContains, scaleBounds } from '../../utils/geo_utils';
import { geoContains, scaleBounds, GeoBoundingBox } from './lib/geo_utils';
import { BUCKET_TYPES } from './bucket_agg_types';
const config = chrome.getUiSettingsClient();
@ -70,15 +69,15 @@ function getPrecision(val: string) {
return precision;
}
const isOutsideCollar = (bounds: unknown, collar: MapCollar) =>
const isOutsideCollar = (bounds: GeoBoundingBox, collar: MapCollar) =>
bounds && collar && !geoContains(collar, bounds);
const geohashGridTitle = i18n.translate('common.ui.aggTypes.buckets.geohashGridTitle', {
defaultMessage: 'Geohash',
});
interface MapCollar {
zoom: unknown;
interface MapCollar extends GeoBoundingBox {
zoom?: unknown;
}
export interface IBucketGeoHashGridAggConfig extends IBucketAggConfig {
@ -148,11 +147,13 @@ export const geoHashBucketAgg = new BucketAggType<IBucketGeoHashGridAggConfig>({
if (params.isFilteredByCollar && agg.getField()) {
const { mapBounds, mapZoom } = params;
if (mapBounds) {
let mapCollar;
let mapCollar: MapCollar;
if (
!agg.lastMapCollar ||
agg.lastMapCollar.zoom !== mapZoom ||
isOutsideCollar(mapBounds, agg.lastMapCollar)
mapBounds &&
(!agg.lastMapCollar ||
agg.lastMapCollar.zoom !== mapZoom ||
isOutsideCollar(mapBounds, agg.lastMapCollar))
) {
mapCollar = scaleBounds(mapBounds);
mapCollar.zoom = mapZoom;

View file

@ -23,7 +23,6 @@ import { npStart } from 'ui/new_platform';
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
import { IpRangeTypeParamEditor } from '../../vis/editors/default/controls/ip_range_type';
import { IpRangesParamEditor } from '../../vis/editors/default/controls/ip_ranges';
import { ipRange } from '../../utils/ip_range';
import { BUCKET_TYPES } from './bucket_agg_types';
// @ts-ignore
@ -59,7 +58,7 @@ export const ipRangeBucketAgg = new BucketAggType({
fieldFormats.getDefaultInstance(KBN_FIELD_TYPES.IP)
);
const IpRangeFormat = FieldFormat.from(function(range: IpRangeKey) {
return ipRange.toString(range, formatter);
return convertIPRangeToString(range, formatter);
});
return new IpRangeFormat();
},
@ -106,3 +105,13 @@ export const ipRangeBucketAgg = new BucketAggType({
},
],
});
export const convertIPRangeToString = (range: IpRangeKey, format: (val: any) => string) => {
if (range.type === 'mask') {
return format(range.mask);
}
const from = range.from ? format(range.from) : '-Infinity';
const to = range.to ? format(range.to) : 'Infinity';
return `${from} to ${to}`;
};

View file

@ -0,0 +1,75 @@
/*
* 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 { CidrMask } from './cidr_mask';
describe('CidrMask', () => {
test('should throw errors with invalid CIDR masks', () => {
expect(
() =>
// @ts-ignore
new CidrMask()
).toThrowError();
expect(() => new CidrMask('')).toThrowError();
expect(() => new CidrMask('hello, world')).toThrowError();
expect(() => new CidrMask('0.0.0.0')).toThrowError();
expect(() => new CidrMask('0.0.0.0/0')).toThrowError();
expect(() => new CidrMask('0.0.0.0/33')).toThrowError();
expect(() => new CidrMask('256.0.0.0/32')).toThrowError();
expect(() => new CidrMask('0.0.0.0/32/32')).toThrowError();
expect(() => new CidrMask('1.2.3/1')).toThrowError();
expect(() => new CidrMask('0.0.0.0/123d')).toThrowError();
});
test('should correctly grab IP address and prefix length', () => {
let mask = new CidrMask('0.0.0.0/1');
expect(mask.initialAddress.toString()).toBe('0.0.0.0');
expect(mask.prefixLength).toBe(1);
mask = new CidrMask('128.0.0.1/31');
expect(mask.initialAddress.toString()).toBe('128.0.0.1');
expect(mask.prefixLength).toBe(31);
});
test('should calculate a range of IP addresses', () => {
let mask = new CidrMask('0.0.0.0/1');
let range = mask.getRange();
expect(range.from.toString()).toBe('0.0.0.0');
expect(range.to.toString()).toBe('127.255.255.255');
mask = new CidrMask('1.2.3.4/2');
range = mask.getRange();
expect(range.from.toString()).toBe('0.0.0.0');
expect(range.to.toString()).toBe('63.255.255.255');
mask = new CidrMask('67.129.65.201/27');
range = mask.getRange();
expect(range.from.toString()).toBe('67.129.65.192');
expect(range.to.toString()).toBe('67.129.65.223');
});
test('toString()', () => {
let mask = new CidrMask('.../1');
expect(mask.toString()).toBe('0.0.0.0/1');
mask = new CidrMask('128.0.0.1/31');
expect(mask.toString()).toBe('128.0.0.1/31');
});
});

View file

@ -17,7 +17,8 @@
* under the License.
*/
import { Ipv4Address } from '../../../../plugins/kibana_utils/public';
import { Ipv4Address } from '../../../../../../plugins/kibana_utils/public';
const NUM_BITS = 32;
function throwError(mask: string) {

View file

@ -19,46 +19,57 @@
import _ from 'lodash';
export function geoContains(collar, bounds) {
//test if bounds top_left is outside collar
if(bounds.top_left.lat > collar.top_left.lat || bounds.top_left.lon < collar.top_left.lon) {
interface GeoBoundingBoxCoordinate {
lat: number;
lon: number;
}
export interface GeoBoundingBox {
top_left: GeoBoundingBoxCoordinate;
bottom_right: GeoBoundingBoxCoordinate;
}
export function geoContains(collar: GeoBoundingBox, bounds: GeoBoundingBox) {
// test if bounds top_left is outside collar
if (bounds.top_left.lat > collar.top_left.lat || bounds.top_left.lon < collar.top_left.lon) {
return false;
}
//test if bounds bottom_right is outside collar
if(bounds.bottom_right.lat < collar.bottom_right.lat || bounds.bottom_right.lon > collar.bottom_right.lon) {
// test if bounds bottom_right is outside collar
if (
bounds.bottom_right.lat < collar.bottom_right.lat ||
bounds.bottom_right.lon > collar.bottom_right.lon
) {
return false;
}
//both corners are inside collar so collar contains bounds
// both corners are inside collar so collar contains bounds
return true;
}
export function scaleBounds(bounds) {
if (!bounds) return;
const scale = .5; // scale bounds by 50%
export function scaleBounds(bounds: GeoBoundingBox): GeoBoundingBox {
const scale = 0.5; // scale bounds by 50%
const topLeft = bounds.top_left;
const bottomRight = bounds.bottom_right;
let latDiff = _.round(Math.abs(topLeft.lat - bottomRight.lat), 5);
const lonDiff = _.round(Math.abs(bottomRight.lon - topLeft.lon), 5);
//map height can be zero when vis is first created
if(latDiff === 0) latDiff = lonDiff;
// map height can be zero when vis is first created
if (latDiff === 0) latDiff = lonDiff;
const latDelta = latDiff * scale;
let topLeftLat = _.round(topLeft.lat, 5) + latDelta;
if(topLeftLat > 90) topLeftLat = 90;
if (topLeftLat > 90) topLeftLat = 90;
let bottomRightLat = _.round(bottomRight.lat, 5) - latDelta;
if(bottomRightLat < -90) bottomRightLat = -90;
if (bottomRightLat < -90) bottomRightLat = -90;
const lonDelta = lonDiff * scale;
let topLeftLon = _.round(topLeft.lon, 5) - lonDelta;
if(topLeftLon < -180) topLeftLon = -180;
if (topLeftLon < -180) topLeftLon = -180;
let bottomRightLon = _.round(bottomRight.lon, 5) + lonDelta;
if(bottomRightLon > 180) bottomRightLon = 180;
if (bottomRightLon > 180) bottomRightLon = 180;
return {
'top_left': { lat: topLeftLat, lon: topLeftLon },
'bottom_right': { lat: bottomRightLat, lon: bottomRightLon }
top_left: { lat: topLeftLat, lon: topLeftLon },
bottom_right: { lat: bottomRightLat, lon: bottomRightLon },
};
}

View file

@ -17,11 +17,10 @@
* under the License.
*/
import _ from 'lodash';
import { ordinalSuffix } from '../ordinal_suffix';
import expect from '@kbn/expect';
import { forOwn } from 'lodash';
import { ordinalSuffix } from './ordinal_suffix';
describe('ordinal suffix util', function () {
describe('ordinal suffix util', () => {
const checks = {
1: 'st',
2: 'nd',
@ -52,19 +51,19 @@ describe('ordinal suffix util', function () {
27: 'th',
28: 'th',
29: 'th',
30: 'th'
30: 'th',
};
_.forOwn(checks, function (expected, num) {
forOwn(checks, (expected, num: any) => {
const int = parseInt(num, 10);
const float = int + Math.random();
it('knowns ' + int, function () {
expect(ordinalSuffix(num)).to.be(num + '' + expected);
it('knowns ' + int, () => {
expect(ordinalSuffix(num)).toBe(num + '' + expected);
});
it('knows ' + float, function () {
expect(ordinalSuffix(num)).to.be(num + '' + expected);
it('knows ' + float, () => {
expect(ordinalSuffix(num)).toBe(num + '' + expected);
});
});
});

View file

@ -18,11 +18,11 @@
*/
// adopted from http://stackoverflow.com/questions/3109978/php-display-number-with-ordinal-suffix
export function ordinalSuffix(num) {
export function ordinalSuffix(num: any): string {
return num + '' + suffix(num);
}
function suffix(num) {
function suffix(num: any): string {
const int = Math.floor(parseFloat(num));
const hunth = int % 100;

View file

@ -28,7 +28,7 @@ import { getPercentileValue } from './percentiles_get_value';
import { PercentilesEditor } from '../../vis/editors/default/controls/percentiles';
// @ts-ignore
import { ordinalSuffix } from '../../utils/ordinal_suffix';
import { ordinalSuffix } from './lib/ordinal_suffix';
export type IPercentileAggConfig = IResponseAggConfig;

View file

@ -1,84 +0,0 @@
/*
* 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 expect from '@kbn/expect';
import { CidrMask } from '../cidr_mask';
describe('CidrMask', () => {
it('should throw errors with invalid CIDR masks', () => {
expect(
() =>
// @ts-ignore
new CidrMask()
).to.throwError();
expect(() => new CidrMask('')).to.throwError();
expect(() => new CidrMask('hello, world')).to.throwError();
expect(() => new CidrMask('0.0.0.0')).to.throwError();
expect(() => new CidrMask('0.0.0.0/0')).to.throwError();
expect(() => new CidrMask('0.0.0.0/33')).to.throwError();
expect(() => new CidrMask('256.0.0.0/32')).to.throwError();
expect(() => new CidrMask('0.0.0.0/32/32')).to.throwError();
expect(() => new CidrMask('1.2.3/1')).to.throwError();
expect(() => new CidrMask('0.0.0.0/123d')).to.throwError();
});
it('should correctly grab IP address and prefix length', () => {
let mask = new CidrMask('0.0.0.0/1');
expect(mask.initialAddress.toString()).to.be('0.0.0.0');
expect(mask.prefixLength).to.be(1);
mask = new CidrMask('128.0.0.1/31');
expect(mask.initialAddress.toString()).to.be('128.0.0.1');
expect(mask.prefixLength).to.be(31);
});
it('should calculate a range of IP addresses', () => {
let mask = new CidrMask('0.0.0.0/1');
let range = mask.getRange();
expect(range.from.toString()).to.be('0.0.0.0');
expect(range.to.toString()).to.be('127.255.255.255');
mask = new CidrMask('1.2.3.4/2');
range = mask.getRange();
expect(range.from.toString()).to.be('0.0.0.0');
expect(range.to.toString()).to.be('63.255.255.255');
mask = new CidrMask('67.129.65.201/27');
range = mask.getRange();
expect(range.from.toString()).to.be('67.129.65.192');
expect(range.to.toString()).to.be('67.129.65.223');
});
it('toString()', () => {
let mask = new CidrMask('.../1');
expect(mask.toString()).to.be('0.0.0.0/1');
mask = new CidrMask('128.0.0.1/31');
expect(mask.toString()).to.be('128.0.0.1/31');
});
});

View file

@ -1,32 +0,0 @@
/*
* 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 { DateRangeKey } from '../agg_types/buckets/date_range';
export const dateRange = {
toString({ from, to }: DateRangeKey, format: (val: any) => string) {
if (!from) {
return 'Before ' + format(to);
} else if (!to) {
return 'After ' + format(from);
} else {
return format(from) + ' to ' + format(to);
}
},
};

View file

@ -1,31 +0,0 @@
/*
* 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 { IpRangeKey } from '../agg_types/buckets/ip_range';
export const ipRange = {
toString(range: IpRangeKey, format: (val: any) => string) {
if (range.type === 'mask') {
return format(range.mask);
}
const from = range.from ? format(range.from) : '-Infinity';
const to = range.to ? format(range.to) : 'Infinity';
return `${from} to ${to}`;
},
};

View file

@ -20,7 +20,7 @@
import React from 'react';
import { EuiFieldText, EuiFlexItem } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { CidrMask } from '../../../../../utils/cidr_mask';
import { CidrMask } from '../../../../../agg_types/buckets/lib/cidr_mask';
import { InputList, InputListConfig, InputObject, InputModel, InputItem } from './input_list';
const EMPTY_STRING = '';

View file

@ -26,10 +26,8 @@ import { SerializedFieldFormat } from 'src/plugins/expressions/public';
import { IFieldFormatId, FieldFormat } from '../../../../../../plugins/data/public';
import { tabifyGetColumns } from '../../../agg_response/tabify/_get_columns';
import { dateRange } from '../../../utils/date_range';
import { ipRange } from '../../../utils/ip_range';
import { DateRangeKey } from '../../../agg_types/buckets/date_range';
import { IpRangeKey } from '../../../agg_types/buckets/ip_range';
import { DateRangeKey, convertDateRangeToString } from '../../../agg_types/buckets/date_range';
import { IpRangeKey, convertIPRangeToString } from '../../../agg_types/buckets/ip_range';
interface TermsFieldFormatParams {
otherBucketLabel: string;
@ -120,14 +118,14 @@ export const getFormat: FormatFactory = mapping => {
const nestedFormatter = mapping.params as SerializedFieldFormat;
const DateRangeFormat = FieldFormat.from((range: DateRangeKey) => {
const format = getFieldFormat(nestedFormatter.id, nestedFormatter.params);
return dateRange.toString(range, format.convert.bind(format));
return convertDateRangeToString(range, format.convert.bind(format));
});
return new DateRangeFormat();
} else if (id === 'ip_range') {
const nestedFormatter = mapping.params as SerializedFieldFormat;
const IpRangeFormat = FieldFormat.from((range: IpRangeKey) => {
const format = getFieldFormat(nestedFormatter.id, nestedFormatter.params);
return ipRange.toString(range, format.convert.bind(format));
return convertIPRangeToString(range, format.convert.bind(format));
});
return new IpRangeFormat();
} else if (isTermsFieldFormat(mapping) && mapping.params) {