mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Lens] Add previous time shift back (#121284)
This commit is contained in:
parent
c3bf4e05df
commit
339f721a86
15 changed files with 233 additions and 48 deletions
|
@ -297,6 +297,9 @@ image::images/lens_time_shift.png[Line chart with week-over-week sales compariso
|
|||
|
||||
. Click *Save and return*.
|
||||
|
||||
Time shifts can be used on any metric. The special shift *previous* will show the time window preceding the currently selected one in the time picker in the top right, spanning the same duration.
|
||||
For example, if *Last 7 days* is selected in the time picker, *previous* will show data from 14 days ago to 7 days ago. This mode can't be used together with date histograms.
|
||||
|
||||
[float]
|
||||
[[compare-time-as-percent]]
|
||||
==== Analyze the percent change between time ranges
|
||||
|
|
|
@ -89,16 +89,16 @@ export function TimeShift({
|
|||
return null;
|
||||
}
|
||||
|
||||
const { isValueTooSmall, isValueNotMultiple, canShift } = getLayerTimeShiftChecks(
|
||||
getDateHistogramInterval(layer, indexPattern, activeData, layerId)
|
||||
);
|
||||
const dateHistogramInterval = getDateHistogramInterval(layer, indexPattern, activeData, layerId);
|
||||
const { isValueTooSmall, isValueNotMultiple, isInvalid, canShift } =
|
||||
getLayerTimeShiftChecks(dateHistogramInterval);
|
||||
|
||||
if (!canShift) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parsedLocalValue = localValue && parseTimeShift(localValue);
|
||||
const isLocalValueInvalid = Boolean(parsedLocalValue === 'invalid');
|
||||
const isLocalValueInvalid = Boolean(parsedLocalValue && isInvalid(parsedLocalValue));
|
||||
const localValueTooSmall = parsedLocalValue && isValueTooSmall(parsedLocalValue);
|
||||
const localValueNotMultiple = parsedLocalValue && isValueNotMultiple(parsedLocalValue);
|
||||
|
||||
|
@ -167,7 +167,10 @@ export function TimeShift({
|
|||
options={timeShiftOptions.filter(({ value }) => {
|
||||
const parsedValue = parseTimeShift(value);
|
||||
return (
|
||||
parsedValue && !isValueTooSmall(parsedValue) && !isValueNotMultiple(parsedValue)
|
||||
parsedValue &&
|
||||
!isValueTooSmall(parsedValue) &&
|
||||
!isValueNotMultiple(parsedValue) &&
|
||||
!(parsedValue === 'previous' && dateHistogramInterval.interval)
|
||||
);
|
||||
})}
|
||||
selectedOptions={getSelectedOption()}
|
||||
|
@ -175,7 +178,7 @@ export function TimeShift({
|
|||
isInvalid={isLocalValueInvalid}
|
||||
onCreateOption={(val) => {
|
||||
const parsedVal = parseTimeShift(val);
|
||||
if (parsedVal !== 'invalid') {
|
||||
if (!isInvalid(parsedVal)) {
|
||||
updateLayer(setTimeShift(columnId, layer, val));
|
||||
} else {
|
||||
setLocalValue(val);
|
||||
|
@ -190,7 +193,7 @@ export function TimeShift({
|
|||
|
||||
const choice = choices[0].value as string;
|
||||
const parsedVal = parseTimeShift(choice);
|
||||
if (parsedVal !== 'invalid') {
|
||||
if (!isInvalid(parsedVal)) {
|
||||
updateLayer(setTimeShift(columnId, layer, choice));
|
||||
} else {
|
||||
setLocalValue(choice);
|
||||
|
|
|
@ -18,7 +18,8 @@ import {
|
|||
} from './utils';
|
||||
import { DEFAULT_TIME_SCALE } from '../../time_scale_utils';
|
||||
import { OperationDefinition } from '..';
|
||||
import { getFormatFromPreviousColumn, getFilter } from '../helpers';
|
||||
import { getFormatFromPreviousColumn, getFilter, combineErrorMessages } from '../helpers';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';
|
||||
|
||||
const ofName = buildLabelFunction((name?: string) => {
|
||||
return i18n.translate('xpack.lens.indexPattern.CounterRateOf', {
|
||||
|
@ -104,13 +105,16 @@ export const counterRateOperation: OperationDefinition<
|
|||
return hasDateField(newIndexPattern);
|
||||
},
|
||||
getErrorMessage: (layer: IndexPatternLayer, columnId: string) => {
|
||||
return getErrorsForDateReference(
|
||||
layer,
|
||||
columnId,
|
||||
i18n.translate('xpack.lens.indexPattern.counterRate', {
|
||||
defaultMessage: 'Counter rate',
|
||||
})
|
||||
);
|
||||
return combineErrorMessages([
|
||||
getErrorsForDateReference(
|
||||
layer,
|
||||
columnId,
|
||||
i18n.translate('xpack.lens.indexPattern.counterRate', {
|
||||
defaultMessage: 'Counter rate',
|
||||
})
|
||||
),
|
||||
getDisallowedPreviousShiftMessage(layer, columnId),
|
||||
]);
|
||||
},
|
||||
getDisabledStatus(indexPattern, layer, layerType) {
|
||||
const opName = i18n.translate('xpack.lens.indexPattern.counterRate', {
|
||||
|
|
|
@ -17,7 +17,8 @@ import {
|
|||
checkForDataLayerType,
|
||||
} from './utils';
|
||||
import { OperationDefinition } from '..';
|
||||
import { getFormatFromPreviousColumn, getFilter } from '../helpers';
|
||||
import { getFormatFromPreviousColumn, getFilter, combineErrorMessages } from '../helpers';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';
|
||||
|
||||
const ofName = buildLabelFunction((name?: string) => {
|
||||
return i18n.translate('xpack.lens.indexPattern.cumulativeSumOf', {
|
||||
|
@ -101,13 +102,16 @@ export const cumulativeSumOperation: OperationDefinition<
|
|||
return true;
|
||||
},
|
||||
getErrorMessage: (layer: IndexPatternLayer, columnId: string) => {
|
||||
return getErrorsForDateReference(
|
||||
layer,
|
||||
columnId,
|
||||
i18n.translate('xpack.lens.indexPattern.cumulativeSum', {
|
||||
defaultMessage: 'Cumulative sum',
|
||||
})
|
||||
);
|
||||
return combineErrorMessages([
|
||||
getErrorsForDateReference(
|
||||
layer,
|
||||
columnId,
|
||||
i18n.translate('xpack.lens.indexPattern.cumulativeSum', {
|
||||
defaultMessage: 'Cumulative sum',
|
||||
})
|
||||
),
|
||||
getDisallowedPreviousShiftMessage(layer, columnId),
|
||||
]);
|
||||
},
|
||||
getDisabledStatus(indexPattern, layer, layerType) {
|
||||
const opName = i18n.translate('xpack.lens.indexPattern.cumulativeSum', {
|
||||
|
|
|
@ -18,7 +18,8 @@ import {
|
|||
} from './utils';
|
||||
import { adjustTimeScaleOnOtherColumnChange } from '../../time_scale_utils';
|
||||
import { OperationDefinition } from '..';
|
||||
import { getFormatFromPreviousColumn, getFilter } from '../helpers';
|
||||
import { getFormatFromPreviousColumn, getFilter, combineErrorMessages } from '../helpers';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';
|
||||
|
||||
const OPERATION_NAME = 'differences';
|
||||
|
||||
|
@ -92,13 +93,16 @@ export const derivativeOperation: OperationDefinition<
|
|||
},
|
||||
onOtherColumnChanged: adjustTimeScaleOnOtherColumnChange,
|
||||
getErrorMessage: (layer: IndexPatternLayer, columnId: string) => {
|
||||
return getErrorsForDateReference(
|
||||
layer,
|
||||
columnId,
|
||||
i18n.translate('xpack.lens.indexPattern.derivative', {
|
||||
defaultMessage: 'Differences',
|
||||
})
|
||||
);
|
||||
return combineErrorMessages([
|
||||
getErrorsForDateReference(
|
||||
layer,
|
||||
columnId,
|
||||
i18n.translate('xpack.lens.indexPattern.derivative', {
|
||||
defaultMessage: 'Differences',
|
||||
})
|
||||
),
|
||||
getDisallowedPreviousShiftMessage(layer, columnId),
|
||||
]);
|
||||
},
|
||||
getDisabledStatus(indexPattern, layer, layerType) {
|
||||
const opName = i18n.translate('xpack.lens.indexPattern.derivative', {
|
||||
|
|
|
@ -21,10 +21,16 @@ import {
|
|||
checkForDataLayerType,
|
||||
} from './utils';
|
||||
import { updateColumnParam } from '../../layer_helpers';
|
||||
import { getFormatFromPreviousColumn, isValidNumber, getFilter } from '../helpers';
|
||||
import {
|
||||
getFormatFromPreviousColumn,
|
||||
isValidNumber,
|
||||
getFilter,
|
||||
combineErrorMessages,
|
||||
} from '../helpers';
|
||||
import { adjustTimeScaleOnOtherColumnChange } from '../../time_scale_utils';
|
||||
import { HelpPopover, HelpPopoverButton } from '../../../help_popover';
|
||||
import type { OperationDefinition, ParamEditorProps } from '..';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';
|
||||
|
||||
const ofName = buildLabelFunction((name?: string) => {
|
||||
return i18n.translate('xpack.lens.indexPattern.movingAverageOf', {
|
||||
|
@ -114,13 +120,16 @@ export const movingAverageOperation: OperationDefinition<
|
|||
},
|
||||
onOtherColumnChanged: adjustTimeScaleOnOtherColumnChange,
|
||||
getErrorMessage: (layer: IndexPatternLayer, columnId: string) => {
|
||||
return getErrorsForDateReference(
|
||||
layer,
|
||||
columnId,
|
||||
i18n.translate('xpack.lens.indexPattern.movingAverage', {
|
||||
defaultMessage: 'Moving average',
|
||||
})
|
||||
);
|
||||
return combineErrorMessages([
|
||||
getErrorsForDateReference(
|
||||
layer,
|
||||
columnId,
|
||||
i18n.translate('xpack.lens.indexPattern.movingAverage', {
|
||||
defaultMessage: 'Moving average',
|
||||
})
|
||||
),
|
||||
getDisallowedPreviousShiftMessage(layer, columnId),
|
||||
]);
|
||||
},
|
||||
getHelpMessage: () => <MovingAveragePopup />,
|
||||
getDisabledStatus(indexPattern, layer, layerType) {
|
||||
|
|
|
@ -16,8 +16,10 @@ import {
|
|||
getInvalidFieldMessage,
|
||||
getSafeName,
|
||||
getFilter,
|
||||
combineErrorMessages,
|
||||
} from './helpers';
|
||||
import { adjustTimeScaleLabelSuffix } from '../time_scale_utils';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';
|
||||
|
||||
const supportedTypes = new Set([
|
||||
'string',
|
||||
|
@ -71,7 +73,10 @@ export const cardinalityOperation: OperationDefinition<CardinalityIndexPatternCo
|
|||
}
|
||||
},
|
||||
getErrorMessage: (layer, columnId, indexPattern) =>
|
||||
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
|
||||
combineErrorMessages([
|
||||
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
|
||||
getDisallowedPreviousShiftMessage(layer, columnId),
|
||||
]),
|
||||
isTransferable: (column, newIndexPattern) => {
|
||||
const newField = newIndexPattern.getFieldByName(column.sourceField);
|
||||
|
||||
|
|
|
@ -11,11 +11,17 @@ import { buildExpressionFunction } from '../../../../../../../src/plugins/expres
|
|||
import { OperationDefinition } from './index';
|
||||
import { FormattedIndexPatternColumn, FieldBasedIndexPatternColumn } from './column_types';
|
||||
import { IndexPatternField } from '../../types';
|
||||
import { getInvalidFieldMessage, getFilter, isColumnFormatted } from './helpers';
|
||||
import {
|
||||
getInvalidFieldMessage,
|
||||
getFilter,
|
||||
isColumnFormatted,
|
||||
combineErrorMessages,
|
||||
} from './helpers';
|
||||
import {
|
||||
adjustTimeScaleLabelSuffix,
|
||||
adjustTimeScaleOnOtherColumnChange,
|
||||
} from '../time_scale_utils';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';
|
||||
|
||||
const countLabel = i18n.translate('xpack.lens.indexPattern.countOf', {
|
||||
defaultMessage: 'Count of records',
|
||||
|
@ -34,7 +40,10 @@ export const countOperation: OperationDefinition<CountIndexPatternColumn, 'field
|
|||
}),
|
||||
input: 'field',
|
||||
getErrorMessage: (layer, columnId, indexPattern) =>
|
||||
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
|
||||
combineErrorMessages([
|
||||
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
|
||||
getDisallowedPreviousShiftMessage(layer, columnId),
|
||||
]),
|
||||
onFieldChange: (oldColumn, field) => {
|
||||
return {
|
||||
...oldColumn,
|
||||
|
|
|
@ -347,8 +347,9 @@ export async function getNamedArgumentSuggestions({
|
|||
if (typeof dateHistogramInterval === 'undefined') return true;
|
||||
const parsedValue = parseTimeShift(value);
|
||||
return (
|
||||
typeof parsedValue === 'string' ||
|
||||
Number.isInteger(parsedValue.asMilliseconds() / dateHistogramInterval)
|
||||
parsedValue !== 'previous' &&
|
||||
(parsedValue === 'invalid' ||
|
||||
Number.isInteger(parsedValue.asMilliseconds() / dateHistogramInterval))
|
||||
);
|
||||
})
|
||||
.map(({ value }) => value),
|
||||
|
|
|
@ -67,6 +67,13 @@ export function getInvalidFieldMessage(
|
|||
return undefined;
|
||||
}
|
||||
|
||||
export function combineErrorMessages(
|
||||
errorMessages: Array<string[] | undefined>
|
||||
): string[] | undefined {
|
||||
const messages = (errorMessages.filter(Boolean) as string[][]).flat();
|
||||
return messages.length ? messages : undefined;
|
||||
}
|
||||
|
||||
export function getSafeName(name: string, indexPattern: IndexPattern): string {
|
||||
const field = indexPattern.getFieldByName(name);
|
||||
return field
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
getFilter,
|
||||
} from './helpers';
|
||||
import { adjustTimeScaleLabelSuffix } from '../time_scale_utils';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';
|
||||
|
||||
function ofName(name: string, timeShift: string | undefined) {
|
||||
return adjustTimeScaleLabelSuffix(
|
||||
|
@ -152,6 +153,7 @@ export const lastValueOperation: OperationDefinition<LastValueIndexPatternColumn
|
|||
if (invalidSortFieldMessage) {
|
||||
errorMessages = [invalidSortFieldMessage];
|
||||
}
|
||||
errorMessages.push(...(getDisallowedPreviousShiftMessage(layer, columnId) || []));
|
||||
return errorMessages.length ? errorMessages : undefined;
|
||||
},
|
||||
buildColumn({ field, previousColumn, indexPattern }, columnParams) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
getInvalidFieldMessage,
|
||||
getSafeName,
|
||||
getFilter,
|
||||
combineErrorMessages,
|
||||
} from './helpers';
|
||||
import {
|
||||
FormattedIndexPatternColumn,
|
||||
|
@ -23,6 +24,7 @@ import {
|
|||
adjustTimeScaleLabelSuffix,
|
||||
adjustTimeScaleOnOtherColumnChange,
|
||||
} from '../time_scale_utils';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';
|
||||
|
||||
type MetricColumn<T> = FormattedIndexPatternColumn &
|
||||
FieldBasedIndexPatternColumn & {
|
||||
|
@ -132,7 +134,13 @@ function buildMetricOperation<T extends MetricColumn<string>>({
|
|||
}).toAst();
|
||||
},
|
||||
getErrorMessage: (layer, columnId, indexPattern) =>
|
||||
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
|
||||
combineErrorMessages([
|
||||
getInvalidFieldMessage(
|
||||
layer.columns[columnId] as FieldBasedIndexPatternColumn,
|
||||
indexPattern
|
||||
),
|
||||
getDisallowedPreviousShiftMessage(layer, columnId),
|
||||
]),
|
||||
filterable: true,
|
||||
documentation: {
|
||||
section: 'elasticsearch',
|
||||
|
|
|
@ -18,10 +18,12 @@ import {
|
|||
isValidNumber,
|
||||
getFilter,
|
||||
isColumnOfType,
|
||||
combineErrorMessages,
|
||||
} from './helpers';
|
||||
import { FieldBasedIndexPatternColumn } from './column_types';
|
||||
import { adjustTimeScaleLabelSuffix } from '../time_scale_utils';
|
||||
import { useDebouncedValue } from '../../../shared_components';
|
||||
import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils';
|
||||
|
||||
export interface PercentileIndexPatternColumn extends FieldBasedIndexPatternColumn {
|
||||
operationType: 'percentile';
|
||||
|
@ -142,7 +144,10 @@ export const percentileOperation: OperationDefinition<
|
|||
).toAst();
|
||||
},
|
||||
getErrorMessage: (layer, columnId, indexPattern) =>
|
||||
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
|
||||
combineErrorMessages([
|
||||
getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
|
||||
getDisallowedPreviousShiftMessage(layer, columnId),
|
||||
]),
|
||||
paramEditor: function PercentileParamEditor({
|
||||
layer,
|
||||
updateLayer,
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getDisallowedPreviousShiftMessage } from './time_shift_utils';
|
||||
import { IndexPatternLayer } from './types';
|
||||
|
||||
describe('time_shift_utils', () => {
|
||||
describe('getDisallowedPreviousShiftMessage', () => {
|
||||
const layer: IndexPatternLayer = {
|
||||
indexPatternId: '',
|
||||
columnOrder: [],
|
||||
columns: {
|
||||
a: {
|
||||
operationType: 'date_histogram',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
label: '',
|
||||
references: [],
|
||||
sourceField: 'timestamp',
|
||||
},
|
||||
b: {
|
||||
operationType: 'count',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
label: 'non shifted',
|
||||
references: [],
|
||||
sourceField: 'records',
|
||||
},
|
||||
c: {
|
||||
operationType: 'count',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
label: 'shifted',
|
||||
timeShift: '1d',
|
||||
references: [],
|
||||
sourceField: 'records',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
it('shoud not produce an error for no shift', () => {
|
||||
expect(getDisallowedPreviousShiftMessage(layer, 'b')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('shoud not produce an error for non-previous shift', () => {
|
||||
expect(getDisallowedPreviousShiftMessage(layer, 'c')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('shoud produce an error for previous shift with date histogram', () => {
|
||||
expect(
|
||||
getDisallowedPreviousShiftMessage(
|
||||
{
|
||||
...layer,
|
||||
columns: { ...layer.columns, c: { ...layer.columns.c, timeShift: 'previous' } },
|
||||
},
|
||||
'c'
|
||||
)
|
||||
).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('shoud not produce an error for previous shift without date histogram', () => {
|
||||
expect(
|
||||
getDisallowedPreviousShiftMessage(
|
||||
{
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
a: { ...layer.columns.a, operationType: 'terms' },
|
||||
c: { ...layer.columns.c, timeShift: 'previous' },
|
||||
},
|
||||
},
|
||||
'c'
|
||||
)
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -81,6 +81,12 @@ export const timeShiftOptions = [
|
|||
}),
|
||||
value: '1y',
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.lens.indexPattern.timeShift.previous', {
|
||||
defaultMessage: 'Previous time range',
|
||||
}),
|
||||
value: 'previous',
|
||||
},
|
||||
];
|
||||
|
||||
export const timeShiftOptionOrder = timeShiftOptions.reduce<{ [key: string]: number }>(
|
||||
|
@ -101,7 +107,7 @@ export function getDateHistogramInterval(
|
|||
(colId) => layer.columns[colId].operationType === 'date_histogram'
|
||||
);
|
||||
if (!dateHistogramColumn && !indexPattern.timeFieldName) {
|
||||
return { canShift: false };
|
||||
return { canShift: false, hasDateHistogram: false };
|
||||
}
|
||||
if (dateHistogramColumn && activeData && activeData[layerId] && activeData[layerId]) {
|
||||
const column = activeData[layerId].columns.find((col) => col.id === dateHistogramColumn);
|
||||
|
@ -112,14 +118,16 @@ export function getDateHistogramInterval(
|
|||
interval: search.aggs.parseInterval(expression),
|
||||
expression,
|
||||
canShift: true,
|
||||
hasDateHistogram: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
return { canShift: true };
|
||||
return { canShift: true, hasDateHistogram: Boolean(dateHistogramColumn) };
|
||||
}
|
||||
|
||||
export function getLayerTimeShiftChecks({
|
||||
interval: dateHistogramInterval,
|
||||
hasDateHistogram,
|
||||
canShift,
|
||||
}: ReturnType<typeof getDateHistogramInterval>) {
|
||||
return {
|
||||
|
@ -140,9 +148,41 @@ export function getLayerTimeShiftChecks({
|
|||
!Number.isInteger(parsedValue.asMilliseconds() / dateHistogramInterval.asMilliseconds())
|
||||
);
|
||||
},
|
||||
isInvalid: (parsedValue: ReturnType<typeof parseTimeShift>) => {
|
||||
return Boolean(
|
||||
parsedValue === 'invalid' || (hasDateHistogram && parsedValue && parsedValue === 'previous')
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function getDisallowedPreviousShiftMessage(
|
||||
layer: IndexPatternLayer,
|
||||
columnId: string
|
||||
): string[] | undefined {
|
||||
const currentColumn = layer.columns[columnId];
|
||||
const hasPreviousShift =
|
||||
currentColumn.timeShift && parseTimeShift(currentColumn.timeShift) === 'previous';
|
||||
if (!hasPreviousShift) {
|
||||
return;
|
||||
}
|
||||
const hasDateHistogram = Object.values(layer.columns).some(
|
||||
(column) => column.operationType === 'date_histogram'
|
||||
);
|
||||
if (!hasDateHistogram) {
|
||||
return;
|
||||
}
|
||||
return [
|
||||
i18n.translate('xpack.lens.indexPattern.dateHistogramTimeShift', {
|
||||
defaultMessage:
|
||||
'In a single layer, you are unable to combine previous time range shift with date histograms. Either use an explicit time shift duration in "{column}" or replace the date histogram.',
|
||||
values: {
|
||||
column: currentColumn.label,
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
export function getStateTimeShiftWarningMessages(
|
||||
state: IndexPatternPrivateState,
|
||||
{ activeData }: FramePublicAPI
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue