Skip to content

Commit

Permalink
[TSVB] Doesn't work correctly with pipeline aggregations in "entire t…
Browse files Browse the repository at this point in the history
…ime range" mode (elastic#105073) (elastic#112076)

* Use date_histogram instead of auto_date_histogram in pipeline aggregations

* Fix ci

* Fix eslint

* start disable parent pipeline aggs and show error

* Fix CI

* Fix eslint

* Fix CI

* Add functional tests

* Some fixes

* Fix lint

* Use agg_utils

* Fix lint

* Fix text

* Fix lint

* Fix tests

* Fixed condition

* Fix math aggregation

* math should pass panel type as prop

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
VladLasitsa and kibanamachine committed Sep 14, 2021
1 parent 60c30c4 commit fb6e27e
Show file tree
Hide file tree
Showing 26 changed files with 352 additions and 144 deletions.
58 changes: 58 additions & 0 deletions src/plugins/vis_type_timeseries/common/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

/* eslint-disable max-classes-per-file */

import { i18n } from '@kbn/i18n';

export class UIError extends Error {
constructor(message: string) {
super(message);
}

public get name() {
return this.constructor.name;
}

public get errBody() {
return this.message;
}
}

export class FieldNotFoundError extends UIError {
constructor(name: string) {
super(
i18n.translate('visTypeTimeseries.errors.fieldNotFound', {
defaultMessage: `Field "{field}" not found`,
values: { field: name },
})
);
}
}

export class ValidateIntervalError extends UIError {
constructor() {
super(
i18n.translate('visTypeTimeseries.errors.maxBucketsExceededErrorMessage', {
defaultMessage:
'Your query attempted to fetch too much data. Reducing the time range or changing the interval used usually fixes the issue.',
})
);
}
}

export class AggNotSupportedInMode extends UIError {
constructor(metricType: string, timeRangeMode: string) {
super(
i18n.translate('visTypeTimeseries.wrongAggregationErrorMessage', {
defaultMessage: 'The aggregation {metricType} is not supported in {timeRangeMode} mode',
values: { metricType, timeRangeMode },
})
);
}
}
21 changes: 1 addition & 20 deletions src/plugins/vis_type_timeseries/common/fields_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,10 @@
* Side Public License, v 1.
*/

import { i18n } from '@kbn/i18n';
import { FieldSpec } from '../../data/common';
import { isNestedField } from '../../data/common';
import { FetchedIndexPattern, SanitizedFieldType } from './types';

export class FieldNotFoundError extends Error {
constructor(name: string) {
super(
i18n.translate('visTypeTimeseries.fields.fieldNotFound', {
defaultMessage: `Field "{field}" not found`,
values: { field: name },
})
);
}

public get name() {
return this.constructor.name;
}

public get errBody() {
return this.message;
}
}
import { FieldNotFoundError } from './errors';

export const extractFieldLabel = (
fields: SanitizedFieldType[],
Expand Down
21 changes: 1 addition & 20 deletions src/plugins/vis_type_timeseries/common/validate_interval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,9 @@
* Side Public License, v 1.
*/

import { i18n } from '@kbn/i18n';
import { GTE_INTERVAL_RE } from './interval_regexp';
import { parseInterval, TimeRangeBounds } from '../../data/common';

export class ValidateIntervalError extends Error {
constructor() {
super(
i18n.translate('visTypeTimeseries.validateInterval.notifier.maxBucketsExceededErrorMessage', {
defaultMessage:
'Your query attempted to fetch too much data. Reducing the time range or changing the interval used usually fixes the issue.',
})
);
}

public get name() {
return this.constructor.name;
}

public get errBody() {
return this.message;
}
}
import { ValidateIntervalError } from './errors';

export function validateInterval(bounds: TimeRangeBounds, interval: string, maxBuckets: number) {
const { min, max } = bounds;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
*/

import React, { useMemo, useEffect, HTMLAttributes } from 'react';
import { EuiCode } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
// @ts-ignore
import { aggToComponent } from '../lib/agg_to_component';
// @ts-ignore
import { isMetricEnabled } from '../../lib/check_ui_restrictions';
import { getInvalidAggComponent } from './invalid_agg';
// @ts-expect-error not typed yet
import { seriesChangeHandler } from '../lib/series_change_handler';
import { checkIfNumericMetric } from '../lib/check_if_numeric_metric';
import { getFormatterType } from '../lib/get_formatter_type';
import { UnsupportedAgg } from './unsupported_agg';
import { TemporaryUnsupportedAgg } from './temporary_unsupported_agg';
import { DATA_FORMATTERS } from '../../../../common/enums';
import type { Metric, Panel, Series, SanitizedFieldType } from '../../../../common/types';
import type { DragHandleProps } from '../../../types';
Expand All @@ -43,9 +44,21 @@ export function Agg(props: AggProps) {
let Component = aggToComponent[model.type];

if (!Component) {
Component = UnsupportedAgg;
Component = getInvalidAggComponent(
<FormattedMessage
id="visTypeTimeseries.agg.aggIsNotSupportedDescription"
defaultMessage="The {modelType} aggregation is no longer supported."
values={{ modelType: <EuiCode>{props.model.type}</EuiCode> }}
/>
);
} else if (!isMetricEnabled(model.type, uiRestrictions)) {
Component = TemporaryUnsupportedAgg;
Component = getInvalidAggComponent(
<FormattedMessage
id="visTypeTimeseries.agg.aggIsUnsupportedForPanelConfigDescription"
defaultMessage="The {modelType} aggregation is not supported for existing panel configuration."
values={{ modelType: <EuiCode>{props.model.type}</EuiCode> }}
/>
);
}

const style = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import React from 'react';
import React, { useContext } from 'react';
import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
// @ts-ignore
Expand All @@ -16,6 +16,8 @@ import { getAggsByType, getAggsByPredicate } from '../../../../common/agg_utils'
import type { Agg } from '../../../../common/agg_utils';
import type { Metric } from '../../../../common/types';
import { TimeseriesUIRestrictions } from '../../../../common/ui_restrictions';
import { PanelModelContext } from '../../contexts/panel_model_context';
import { PANEL_TYPES, TIME_RANGE_DATA_MODES } from '../../../../common/enums';

type AggSelectOption = EuiComboBoxOptionOption;

Expand All @@ -35,16 +37,35 @@ function filterByPanelType(panelType: string) {
panelType === 'table' ? agg.value !== TSVB_METRIC_TYPES.SERIES_AGG : true;
}

export function isMetricAvailableForPanel(
aggId: string,
panelType: string,
timeRangeMode?: string
) {
if (
panelType !== PANEL_TYPES.TIMESERIES &&
timeRangeMode === TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE
) {
return (
!pipelineAggs.some((agg) => agg.value === aggId) && aggId !== TSVB_METRIC_TYPES.SERIES_AGG
);
}

return true;
}

interface AggSelectUiProps {
id: string;
panelType: string;
siblings: Metric[];
value: string;
uiRestrictions?: TimeseriesUIRestrictions;
timeRangeMode?: string;
onChange: (currentlySelectedOptions: AggSelectOption[]) => void;
}

export function AggSelect(props: AggSelectUiProps) {
const panelModel = useContext(PanelModelContext);
const { siblings, panelType, value, onChange, uiRestrictions, ...rest } = props;

const selectedOptions = allAggOptions.filter((option) => {
Expand All @@ -69,7 +90,10 @@ export function AggSelect(props: AggSelectUiProps) {
} else {
const disableSiblingAggs = (agg: AggSelectOption) => ({
...agg,
disabled: !enablePipelines || !isMetricEnabled(agg.value, uiRestrictions),
disabled:
!enablePipelines ||
!isMetricEnabled(agg.value, uiRestrictions) ||
!isMetricAvailableForPanel(agg.value as string, panelType, panelModel?.time_range_mode),
});

options = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
*/

import React from 'react';
import { EuiCode, EuiTitle } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiTitle } from '@elastic/eui';
import { AggRow } from './agg_row';
import type { Metric } from '../../../../common/types';
import { DragHandleProps } from '../../../types';

interface UnsupportedAggProps {
interface InvalidAggProps {
disableDelete: boolean;
model: Metric;
siblings: Metric[];
Expand All @@ -22,7 +21,9 @@ interface UnsupportedAggProps {
onDelete: () => void;
}

export function UnsupportedAgg(props: UnsupportedAggProps) {
export const getInvalidAggComponent = (message: JSX.Element | string) => (
props: InvalidAggProps
) => {
return (
<AggRow
disableDelete={props.disableDelete}
Expand All @@ -32,15 +33,9 @@ export function UnsupportedAgg(props: UnsupportedAggProps) {
siblings={props.siblings}
dragHandleProps={props.dragHandleProps}
>
<EuiTitle className="tvbAggRow__unavailable" size="xxxs">
<span>
<FormattedMessage
id="visTypeTimeseries.unsupportedAgg.aggIsNotSupportedDescription"
defaultMessage="The {modelType} aggregation is no longer supported."
values={{ modelType: <EuiCode>{props.model.type}</EuiCode> }}
/>
</span>
<EuiTitle className="tvbAggRow__unavailable" size="xxxs" data-test-subj="invalid_agg">
<span>{message}</span>
</EuiTitle>
</AggRow>
);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export function MathAgg(props) {
id={htmlId('aggregation')}
siblings={props.siblings}
value={model.type}
panelType={props.panel.type}
onChange={handleSelectChange('type')}
/>
</EuiFlexItem>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
*/

import { DefaultSearchCapabilities } from './default_search_capabilities';
import type { Panel } from '../../../../common/types';

describe('DefaultSearchCapabilities', () => {
let defaultSearchCapabilities: DefaultSearchCapabilities;

beforeEach(() => {
defaultSearchCapabilities = new DefaultSearchCapabilities({
panel: {} as Panel,
timezone: 'UTC',
maxBucketsLimit: 2000,
});
Expand Down
Loading

0 comments on commit fb6e27e

Please sign in to comment.