From 85525e84a0a4469d7d91de67e61828dea26719f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Jamr=C3=B3z?= Date: Thu, 31 Mar 2022 12:04:51 +0200 Subject: [PATCH] [v8.4.x] Explore: Fix time interpolation (#46737) (#47114) * Explore: Fix time interpolation (#46737) * Ensure TemplateService is updated with new time range on each time range change. * Fix linting errors * Fix explorePane.test.ts * Reuse createDefaultInitialState * Remove unused imports * Add a test for left/right split * Silence console.error in tests * Silence console.error in tests (cherry picked from commit bf977ac2456cd8cdd136a992489260c861d8fe03) # Conflicts: # .betterer.results # packages/grafana-runtime/src/services/templateSrv.ts # public/app/features/explore/spec/helper/setup.tsx # public/app/features/explore/state/query.test.ts # public/app/features/explore/state/time.ts # public/app/features/explore/utils/links.test.ts # public/app/features/templating/template_srv.mock.ts # public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx * Add missing mocks * Add missing mocks --- .../src/services/templateSrv.ts | 7 +++++- .../explore/state/explorePane.test.ts | 8 +++++++ .../app/features/explore/state/query.test.ts | 15 +++++++++++++ public/app/features/explore/state/time.ts | 22 +++++++++++++------ .../app/features/explore/utils/links.test.ts | 1 + .../features/templating/template_srv.mock.ts | 4 +++- .../loki/configuration/DebugSection.test.tsx | 3 ++- 7 files changed, 50 insertions(+), 10 deletions(-) diff --git a/packages/grafana-runtime/src/services/templateSrv.ts b/packages/grafana-runtime/src/services/templateSrv.ts index 962dacd70c2..6af1575503f 100644 --- a/packages/grafana-runtime/src/services/templateSrv.ts +++ b/packages/grafana-runtime/src/services/templateSrv.ts @@ -1,4 +1,4 @@ -import { VariableModel, ScopedVars } from '@grafana/data'; +import { VariableModel, ScopedVars, TimeRange } from '@grafana/data'; /** * Via the TemplateSrv consumers get access to all the available template variables @@ -17,6 +17,11 @@ export interface TemplateSrv { * Replace the values within the target string. See also {@link InterpolateFunction} */ replace(target?: string, scopedVars?: ScopedVars, format?: string | Function): string; + + /** + * Update the current time range to be used when interpolating __from / __to variables. + */ + updateTimeRange(timeRange: TimeRange): void; } let singletonInstance: TemplateSrv; diff --git a/public/app/features/explore/state/explorePane.test.ts b/public/app/features/explore/state/explorePane.test.ts index fc4ce58c208..98b2ea3de50 100644 --- a/public/app/features/explore/state/explorePane.test.ts +++ b/public/app/features/explore/state/explorePane.test.ts @@ -8,6 +8,14 @@ import { of } from 'rxjs'; jest.mock('../../dashboard/services/TimeSrv', () => ({ getTimeSrv: jest.fn().mockReturnValue({ init: jest.fn(), + timeRange: jest.fn().mockReturnValue({}), + }), +})); + +jest.mock('@grafana/runtime', () => ({ + ...(jest.requireActual('@grafana/runtime') as unknown as object), + getTemplateSrv: () => ({ + updateTimeRange: jest.fn(), }), })); diff --git a/public/app/features/explore/state/query.test.ts b/public/app/features/explore/state/query.test.ts index 2accb2fa55b..794c67e268a 100644 --- a/public/app/features/explore/state/query.test.ts +++ b/public/app/features/explore/state/query.test.ts @@ -35,6 +35,21 @@ import { configureStore } from '../../../store/configureStore'; import { setTimeSrv } from '../../dashboard/services/TimeSrv'; import Mock = jest.Mock; +jest.mock('app/features/dashboard/services/TimeSrv', () => ({ + ...jest.requireActual('app/features/dashboard/services/TimeSrv'), + getTimeSrv: () => ({ + init: jest.fn(), + timeRange: jest.fn().mockReturnValue({}), + }), +})); + +jest.mock('@grafana/runtime', () => ({ + ...(jest.requireActual('@grafana/runtime') as unknown as object), + getTemplateSrv: () => ({ + updateTimeRange: jest.fn(), + }), +})); + const t = toUtc(); const testRange = { from: t, diff --git a/public/app/features/explore/state/time.ts b/public/app/features/explore/state/time.ts index 9d8e7ab3c4b..6b0d5dbdc79 100644 --- a/public/app/features/explore/state/time.ts +++ b/public/app/features/explore/state/time.ts @@ -8,6 +8,7 @@ import { TimeRange, } from '@grafana/data'; import { RefreshPicker } from '@grafana/ui'; +import { getTemplateSrv } from '@grafana/runtime'; import { getTimeRange, refreshIntervalToSortOrder, stopQueryState } from 'app/core/utils/explore'; import { ExploreItemState, ThunkResult } from 'app/types'; @@ -95,15 +96,22 @@ export const updateTime = (config: { const range = getTimeRange(timeZone, rawRange, fiscalYearStartMonth); const absoluteRange: AbsoluteTimeRange = { from: range.from.valueOf(), to: range.to.valueOf() }; - - getTimeSrv().init( - new DashboardModel({ - time: range.raw, - refresh: false, - timeZone, - }) + const timeModel: DashboardModel = Object.assign( + new DashboardModel({ time: range.raw, refresh: false, timepicker: {} }), + { + getTimezone: () => timeZone, + timeRangeUpdated: (rawTimeRange: RawTimeRange) => { + dispatch(updateTimeRange({ exploreId: exploreId, rawRange: rawTimeRange })); + }, + } ); + // We need to re-initialize TimeSrv because it might have been triggered by the other Explore pane (when split) + getTimeSrv().init(timeModel); + // After re-initializing TimeSrv we need to update the time range in Template service for interpolation + // of __from and __to variables + getTemplateSrv().updateTimeRange(getTimeSrv().timeRange()); + dispatch(changeRangeAction({ exploreId, range, absoluteRange })); }; }; diff --git a/public/app/features/explore/utils/links.test.ts b/public/app/features/explore/utils/links.test.ts index 7d049b48197..326eff73da9 100644 --- a/public/app/features/explore/utils/links.test.ts +++ b/public/app/features/explore/utils/links.test.ts @@ -22,6 +22,7 @@ describe('getFieldLinksForExplore', () => { getVariables() { return []; }, + updateTimeRange(timeRange: TimeRange) {}, }); }); diff --git a/public/app/features/templating/template_srv.mock.ts b/public/app/features/templating/template_srv.mock.ts index 394223a75c0..85864f76028 100644 --- a/public/app/features/templating/template_srv.mock.ts +++ b/public/app/features/templating/template_srv.mock.ts @@ -1,4 +1,4 @@ -import { ScopedVars, VariableModel } from '@grafana/data'; +import { ScopedVars, TimeRange, VariableModel } from '@grafana/data'; import { variableRegex } from '../variables/utils'; import { TemplateSrv } from '@grafana/runtime'; @@ -45,4 +45,6 @@ export class TemplateSrvMock implements TemplateSrv { } return match.slice(1).find((match) => match !== undefined); } + + updateTimeRange(timeRange: TimeRange) {} } diff --git a/public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx b/public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx index a530a5c7d74..bc466208d33 100644 --- a/public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx +++ b/public/app/plugins/datasource/loki/configuration/DebugSection.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; -import { dateTime } from '@grafana/data'; +import { dateTime, TimeRange } from '@grafana/data'; import { setTemplateSrv } from '@grafana/runtime'; import { DebugSection } from './DebugSection'; @@ -35,6 +35,7 @@ describe('DebugSection', () => { getVariables() { return []; }, + updateTimeRange(timeRange: TimeRange) {}, }); });