diff --git a/docs/user/dashboard/lens-advanced.asciidoc b/docs/user/dashboard/lens-advanced.asciidoc
index eaa2014717714..a115dfbc30474 100644
--- a/docs/user/dashboard/lens-advanced.asciidoc
+++ b/docs/user/dashboard/lens-advanced.asciidoc
@@ -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
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_shift.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_shift.tsx
index 1baab99c99b09..b7563f28aac5c 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_shift.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_shift.tsx
@@ -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);
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx
index 8cc6139fedc0a..3f051286f3da9 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx
@@ -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', {
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx
index a59491cfc8a6b..6a05c80702797 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx
@@ -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', {
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx
index 730067e9c5577..31b21327958d7 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx
@@ -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', {
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx
index 026b1bf7fd64a..1a8519e6a60a1 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx
@@ -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: () => ,
getDisabledStatus(indexPattern, layer, layerType) {
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx
index 72c1362896ac0..c97447803524d 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx
@@ -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
- 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);
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx
index 6290abac77844..a35f8fbc08acf 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx
@@ -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
- getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
+ combineErrorMessages([
+ getInvalidFieldMessage(layer.columns[columnId] as FieldBasedIndexPatternColumn, indexPattern),
+ getDisallowedPreviousShiftMessage(layer, columnId),
+ ]),
onFieldChange: (oldColumn, field) => {
return {
...oldColumn,
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts
index 28e762e7dff0f..ece41a95130bf 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts
@@ -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),
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx
index 9b22ef02fb3b5..73e0e61a68950 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx
@@ -67,6 +67,13 @@ export function getInvalidFieldMessage(
return undefined;
}
+export function combineErrorMessages(
+ errorMessages: Array
+): 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
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx
index 46e1b368fc913..7a73a1a0b6c24 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx
@@ -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 = FormattedIndexPatternColumn &
FieldBasedIndexPatternColumn & {
@@ -132,7 +134,13 @@ function buildMetricOperation>({
}).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',
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx
index d1ce42696ea68..73536ae4893a6 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx
@@ -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,
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.test.tsx
new file mode 100644
index 0000000000000..4cb251e3820be
--- /dev/null
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.test.tsx
@@ -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();
+ });
+ });
+});
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx
index 4e18e2f376c70..90353ac087436 100644
--- a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx
+++ b/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx
@@ -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) {
return {
@@ -140,9 +148,41 @@ export function getLayerTimeShiftChecks({
!Number.isInteger(parsedValue.asMilliseconds() / dateHistogramInterval.asMilliseconds())
);
},
+ isInvalid: (parsedValue: ReturnType) => {
+ 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