Browse Source

Explore: Fixes incorrect handling of utc in timeEpic (#18386)

* Fix: Fixes incorrect handling of utc in timeEpic

* Chore: Renames dateTimeFromTimeZone to dateTimeForTimeZone
Hugo Häggmark 6 years ago
parent
commit
ead2d6e88f

+ 2 - 6
packages/grafana-data/src/utils/datemath.ts

@@ -1,6 +1,6 @@
 import includes from 'lodash/includes';
 import isDate from 'lodash/isDate';
-import { DateTime, dateTime, toUtc, ISO_8601, isDateTime, DurationUnit } from './moment_wrapper';
+import { DateTime, dateTime, dateTimeForTimeZone, ISO_8601, isDateTime, DurationUnit } from './moment_wrapper';
 import { TimeZone } from '../types';
 
 const units: DurationUnit[] = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
@@ -45,11 +45,7 @@ export function parse(text: string | DateTime | Date, roundUp?: boolean, timezon
     let parseString;
 
     if (text.substring(0, 3) === 'now') {
-      if (timezone === 'utc') {
-        time = toUtc();
-      } else {
-        time = dateTime();
-      }
+      time = dateTimeForTimeZone(timezone);
       mathString = text.substring('now'.length);
     } else {
       index = text.indexOf('||');

+ 13 - 0
packages/grafana-data/src/utils/moment_wrapper.ts

@@ -1,3 +1,4 @@
+import { TimeZone } from '../types/time';
 /* tslint:disable:import-blacklist ban ban-types */
 import moment, { MomentInput, DurationInputArg1 } from 'moment';
 
@@ -96,3 +97,15 @@ export const toDuration = (input?: DurationInput, unit?: DurationUnit): DateTime
 export const dateTime = (input?: DateTimeInput, formatInput?: FormatInput): DateTime => {
   return moment(input as MomentInput, formatInput) as DateTime;
 };
+
+export const dateTimeForTimeZone = (
+  timezone?: TimeZone,
+  input?: DateTimeInput,
+  formatInput?: FormatInput
+): DateTime => {
+  if (timezone === 'utc') {
+    return toUtc(input, formatInput);
+  }
+
+  return dateTime(input, formatInput);
+};

+ 2 - 6
packages/grafana-ui/src/components/TimePicker/time.ts

@@ -8,7 +8,7 @@ import {
   isDateTime,
   dateTime,
   DateTime,
-  toUtc,
+  dateTimeForTimeZone,
 } from '@grafana/data';
 
 export const rawToTimeRange = (raw: RawTimeRange, timeZone?: TimeZone): TimeRange => {
@@ -32,11 +32,7 @@ export const stringToDateTimeType = (value: string | DateTime, roundUp?: boolean
     return parsed || dateTime();
   }
 
-  if (timeZone === 'utc') {
-    return toUtc(value, TIME_FORMAT);
-  }
-
-  return dateTime(value, TIME_FORMAT);
+  return dateTimeForTimeZone(timeZone, value, TIME_FORMAT);
 };
 
 export const mapTimeRangeToRangeString = (timeRange: RawTimeRange): string => {

+ 5 - 5
public/app/features/explore/ExploreTimeControls.tsx

@@ -3,7 +3,7 @@ import React, { Component } from 'react';
 
 // Types
 import { ExploreId } from 'app/types';
-import { TimeRange, TimeOption, TimeZone, toUtc, dateTime, RawTimeRange } from '@grafana/data';
+import { TimeRange, TimeOption, TimeZone, RawTimeRange, dateTimeForTimeZone } from '@grafana/data';
 
 // State
 
@@ -32,8 +32,8 @@ export class ExploreTimeControls extends Component<Props> {
     const { range, onChangeTime, timeZone } = this.props;
     const { from, to } = getShiftedTimeRange(direction, range);
     const nextTimeRange = {
-      from: timeZone === 'utc' ? toUtc(from) : dateTime(from),
-      to: timeZone === 'utc' ? toUtc(to) : dateTime(to),
+      from: dateTimeForTimeZone(timeZone, from),
+      to: dateTimeForTimeZone(timeZone, to),
     };
 
     onChangeTime(nextTimeRange);
@@ -50,8 +50,8 @@ export class ExploreTimeControls extends Component<Props> {
     const { range, onChangeTime, timeZone } = this.props;
     const { from, to } = getZoomedTimeRange(range, 2);
     const nextTimeRange = {
-      from: timeZone === 'utc' ? toUtc(from) : dateTime(from),
-      to: timeZone === 'utc' ? toUtc(to) : dateTime(to),
+      from: dateTimeForTimeZone(timeZone, from),
+      to: dateTimeForTimeZone(timeZone, to),
     };
 
     onChangeTime(nextTimeRange);

+ 1 - 1
public/app/features/explore/state/epics/timeEpic.test.ts

@@ -62,7 +62,7 @@ describe('timeEpic', () => {
             .thenDependencyWasCalledTimes(1, 'getTimeSrv', 'init')
             .thenDependencyWasCalledTimes(1, 'getTimeRange')
             .thenDependencyWasCalledWith([DefaultTimeZone, { from: null, to: null }], 'getTimeRange')
-            .thenDependencyWasCalledTimes(2, 'dateTime')
+            .thenDependencyWasCalledTimes(2, 'dateTimeForTimeZone')
             .thenResultingActionsEqual(
               changeRangeAction({
                 exploreId,

+ 6 - 5
public/app/features/explore/state/epics/timeEpic.ts

@@ -5,11 +5,12 @@ import { AbsoluteTimeRange, RawTimeRange } from '@grafana/data';
 import { ActionOf } from 'app/core/redux/actionCreatorFactory';
 import { StoreState } from 'app/types/store';
 import { updateTimeRangeAction, UpdateTimeRangePayload, changeRangeAction } from '../actionTypes';
+import { EpicDependencies } from 'app/store/configureStore';
 
-export const timeEpic: Epic<ActionOf<any>, ActionOf<any>, StoreState> = (
+export const timeEpic: Epic<ActionOf<any>, ActionOf<any>, StoreState, EpicDependencies> = (
   action$,
   state$,
-  { getTimeSrv, getTimeRange, getTimeZone, toUtc, dateTime }
+  { getTimeSrv, getTimeRange, getTimeZone, dateTimeForTimeZone }
 ) => {
   return action$.ofType(updateTimeRangeAction.type).pipe(
     map((action: ActionOf<UpdateTimeRangePayload>) => {
@@ -21,8 +22,8 @@ export const timeEpic: Epic<ActionOf<any>, ActionOf<any>, StoreState> = (
 
       if (absRange) {
         rawRange = {
-          from: timeZone.isUtc ? toUtc(absRange.from) : dateTime(absRange.from),
-          to: timeZone.isUtc ? toUtc(absRange.to) : dateTime(absRange.to),
+          from: dateTimeForTimeZone(timeZone, absRange.from),
+          to: dateTimeForTimeZone(timeZone, absRange.to),
         };
       }
 
@@ -36,7 +37,7 @@ export const timeEpic: Epic<ActionOf<any>, ActionOf<any>, StoreState> = (
       getTimeSrv().init({
         time: range.raw,
         refresh: false,
-        getTimezone: () => timeZone.raw,
+        getTimezone: () => timeZone,
         timeRangeUpdated: (): any => undefined,
       });
 

+ 3 - 6
public/app/store/configureStore.ts

@@ -37,9 +37,8 @@ import {
   DateTimeInput,
   FormatInput,
   DateTime,
-  toUtc,
-  dateTime,
   AbsoluteTimeRange,
+  dateTimeForTimeZone,
 } from '@grafana/data';
 import { Observable } from 'rxjs';
 import { getQueryResponse } from 'app/core/utils/explore';
@@ -90,9 +89,8 @@ export interface EpicDependencies {
   getTimeSrv: () => TimeSrv;
   getTimeRange: (timeZone: TimeZone, rawRange: RawTimeRange) => TimeRange;
   getTimeZone: (state: UserState) => TimeZone;
-  toUtc: (input?: DateTimeInput, formatInput?: FormatInput) => DateTime;
-  dateTime: (input?: DateTimeInput, formatInput?: FormatInput) => DateTime;
   getShiftedTimeRange: (direction: number, origRange: TimeRange, timeZone: TimeZone) => AbsoluteTimeRange;
+  dateTimeForTimeZone: (timezone?: TimeZone, input?: DateTimeInput, formatInput?: FormatInput) => DateTime;
 }
 
 const dependencies: EpicDependencies = {
@@ -100,9 +98,8 @@ const dependencies: EpicDependencies = {
   getTimeSrv,
   getTimeRange,
   getTimeZone,
-  toUtc,
-  dateTime,
   getShiftedTimeRange,
+  dateTimeForTimeZone,
 };
 
 const epicMiddleware = createEpicMiddleware({ dependencies });

+ 2 - 5
public/test/core/redux/epicTester.ts

@@ -54,18 +54,15 @@ export const epicTester = (
 
   const getTimeZone = jest.fn().mockReturnValue(DefaultTimeZone);
 
-  const toUtc = jest.fn().mockReturnValue(null);
-
-  const dateTime = jest.fn().mockReturnValue(null);
+  const dateTimeForTimeZone = jest.fn().mockReturnValue(null);
 
   const defaultDependencies: EpicDependencies = {
     getQueryResponse,
     getTimeSrv,
     getTimeRange,
     getTimeZone,
-    toUtc,
-    dateTime,
     getShiftedTimeRange,
+    dateTimeForTimeZone,
   };
 
   const theDependencies: EpicDependencies = { ...defaultDependencies, ...dependencies };