diff --git a/packages/grafana-ui/src/components/Graph/mockGraphWithLegendData.ts b/packages/grafana-ui/src/components/Graph/mockGraphWithLegendData.ts index 2e150eb04ea..54d3a354b27 100644 --- a/packages/grafana-ui/src/components/Graph/mockGraphWithLegendData.ts +++ b/packages/grafana-ui/src/components/Graph/mockGraphWithLegendData.ts @@ -1,6 +1,6 @@ import { GraphWithLegendProps } from './GraphWithLegend'; -import moment from 'moment'; import { LegendDisplayMode } from '../Legend/Legend'; +import { dateTime } from '../../utils/moment_wrapper'; // import { LegendList } from '../Legend/LegendList'; export const mockGraphWithLegendData = ({ @@ -3287,8 +3287,8 @@ export const mockGraphWithLegendData = ({ }, ], timeRange: { - from: moment('2019-04-09T07:01:14.247Z'), - to: moment('2019-04-09T13:01:14.247Z'), + from: dateTime('2019-04-09T07:01:14.247Z'), + to: dateTime('2019-04-09T13:01:14.247Z'), raw: { from: 'now-6h', to: 'now', diff --git a/packages/grafana-ui/src/components/Table/TableCellBuilder.tsx b/packages/grafana-ui/src/components/Table/TableCellBuilder.tsx index ad504721dbd..f7e54d7bb5d 100644 --- a/packages/grafana-ui/src/components/Table/TableCellBuilder.tsx +++ b/packages/grafana-ui/src/components/Table/TableCellBuilder.tsx @@ -3,11 +3,11 @@ import _ from 'lodash'; import React, { ReactElement } from 'react'; import { GridCellProps } from 'react-virtualized'; import { Table, Props } from './Table'; -import moment from 'moment'; import { ValueFormatter, getValueFormat, getColorFromHexRgbOrName } from '../../utils/index'; import { GrafanaTheme } from '../../types/theme'; import { InterpolateFunction } from '../../types/panel'; import { Field } from '../../types/data'; +import { dateTime } from '../../utils/moment_wrapper'; export interface TableCellBuilderOptions { value: any; @@ -96,7 +96,7 @@ export function getCellBuilder(schema: Field, style: ColumnStyle | null, props: if (_.isArray(v)) { v = v[0]; } - let date = moment(v); + let date = dateTime(v); if (false) { // TODO?????? this.props.isUTC) { date = date.utc(); diff --git a/packages/grafana-ui/src/components/TimePicker/TimePicker.story.tsx b/packages/grafana-ui/src/components/TimePicker/TimePicker.story.tsx index 18cdf822583..36c6eaf3f11 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePicker.story.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePicker.story.tsx @@ -1,11 +1,12 @@ import React from 'react'; -import moment, { Moment } from 'moment'; import { storiesOf } from '@storybook/react'; import { action } from '@storybook/addon-actions'; import { TimePicker } from './TimePicker'; import { UseState } from '../../utils/storybook/UseState'; import { withRighAlignedStory } from '../../utils/storybook/withRightAlignedStory'; +import { TimeFragment } from '../../types/time'; +import { dateTime } from '../../utils/moment_wrapper'; const TimePickerStories = storiesOf('UI/TimePicker', module); export const popoverOptions = { @@ -177,9 +178,9 @@ TimePickerStories.add('default', () => { return ( {(value, updateValue) => { diff --git a/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx b/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx index f25c5e6452e..5fb625df257 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePicker.tsx @@ -1,5 +1,4 @@ import React, { PureComponent } from 'react'; -import moment from 'moment'; import { ButtonSelect } from '../Select/ButtonSelect'; import { mapTimeOptionToTimeRange, mapTimeRangeToRangeString } from './time'; import { Props as TimePickerPopoverProps } from './TimePickerPopover'; @@ -8,6 +7,7 @@ import { PopperContent } from '../Tooltip/PopperController'; import { Timezone } from '../../utils/datemath'; import { TimeRange, TimeOption, TimeOptions } from '../../types/time'; import { SelectOptionItem } from '../Select/Select'; +import { isDateTime } from '../../utils/moment_wrapper'; export interface Props { value: TimeRange; @@ -266,7 +266,7 @@ export class TimePicker extends PureComponent { } = this.props; const options = this.mapTimeOptionsToSelectOptionItems(selectTimeOptions); const rangeString = mapTimeRangeToRangeString(value); - const isAbsolute = moment.isMoment(value.raw.to); + const isAbsolute = isDateTime(value.raw.to); return (
diff --git a/packages/grafana-ui/src/components/TimePicker/TimePickerCalendar.story.tsx b/packages/grafana-ui/src/components/TimePicker/TimePickerCalendar.story.tsx index 3cc044430b1..5a6687d17fc 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePickerCalendar.story.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePickerCalendar.story.tsx @@ -1,18 +1,18 @@ import React from 'react'; import { storiesOf } from '@storybook/react'; import { action } from '@storybook/addon-actions'; -import { Moment } from 'moment'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { TimePickerCalendar } from './TimePickerCalendar'; import { UseState } from '../../utils/storybook/UseState'; +import { TimeFragment } from '../../types/time'; const TimePickerCalendarStories = storiesOf('UI/TimePicker/TimePickerCalendar', module); TimePickerCalendarStories.addDecorator(withCenteredStory); TimePickerCalendarStories.add('default', () => ( - + {(value, updateValue) => { return ( void; + onChange: (value: DateTime) => void; } export class TimePickerCalendar extends PureComponent { @@ -22,15 +22,15 @@ export class TimePickerCalendar extends PureComponent { return; } - onChange(moment(date)); + onChange(dateTime(date)); }; render() { const { value, isTimezoneUtc, roundup, timezone } = this.props; - const dateValue = moment.isMoment(value) + const dateValue = isDateTime(value) ? value.toDate() - : stringToMoment(value, isTimezoneUtc, roundup, timezone).toDate(); - const calendarValue = dateValue instanceof Date && !isNaN(dateValue.getTime()) ? dateValue : moment().toDate(); + : stringToDateTimeType(value, isTimezoneUtc, roundup, timezone).toDate(); + const calendarValue = dateValue instanceof Date && !isNaN(dateValue.getTime()) ? dateValue : dateTime().toDate(); return ( { return isValid; } - const parsed = stringToMoment(value, isTimezoneUtc); + const parsed = stringToDateTimeType(value, isTimezoneUtc); const isValid = parsed.isValid(); return isValid; }; @@ -35,7 +34,7 @@ export class TimePickerInput extends PureComponent { }; valueToString = (value: TimeFragment) => { - if (moment.isMoment(value)) { + if (isDateTime(value)) { return value.format(TIME_FORMAT); } else { return value; diff --git a/packages/grafana-ui/src/components/TimePicker/TimePickerOptionGroup.story.tsx b/packages/grafana-ui/src/components/TimePicker/TimePickerOptionGroup.story.tsx index e5d104d9921..795c536ece2 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePickerOptionGroup.story.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePickerOptionGroup.story.tsx @@ -1,12 +1,12 @@ import React, { ComponentType } from 'react'; import { storiesOf } from '@storybook/react'; -import moment from 'moment'; import { action } from '@storybook/addon-actions'; import { TimePickerOptionGroup } from './TimePickerOptionGroup'; import { TimeRange } from '../../types/time'; import { withRighAlignedStory } from '../../utils/storybook/withRightAlignedStory'; import { popoverOptions } from './TimePicker.story'; +import { dateTime } from '../../utils/moment_wrapper'; const TimePickerOptionGroupStories = storiesOf('UI/TimePicker/TimePickerOptionGroup', module); @@ -21,7 +21,7 @@ const data = { action('onPopoverClose fired')(timeRange); }, popoverProps: { - value: { from: moment(), to: moment(), raw: { from: 'now/d', to: 'now/d' } }, + value: { from: dateTime(), to: dateTime(), raw: { from: 'now/d', to: 'now/d' } }, options: popoverOptions, isTimezoneUtc: false, onChange: (timeRange: TimeRange) => { diff --git a/packages/grafana-ui/src/components/TimePicker/TimePickerPopover.story.tsx b/packages/grafana-ui/src/components/TimePicker/TimePickerPopover.story.tsx index 38f5e48bbe0..03dfaa1fb63 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePickerPopover.story.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePickerPopover.story.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; -import moment, { Moment } from 'moment'; import { storiesOf } from '@storybook/react'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { TimePickerPopover } from './TimePickerPopover'; import { UseState } from '../../utils/storybook/UseState'; import { popoverOptions } from './TimePicker.story'; +import { dateTime, DateTime } from '../../utils/moment_wrapper'; const TimePickerPopoverStories = storiesOf('UI/TimePicker/TimePickerPopover', module); @@ -15,9 +15,9 @@ TimePickerPopoverStories.addDecorator(withCenteredStory); TimePickerPopoverStories.add('default', () => ( {(value, updateValue) => { diff --git a/packages/grafana-ui/src/components/TimePicker/TimePickerPopover.tsx b/packages/grafana-ui/src/components/TimePicker/TimePickerPopover.tsx index 03676598089..37c05863a03 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimePickerPopover.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimePickerPopover.tsx @@ -1,11 +1,11 @@ import React, { Component, SyntheticEvent } from 'react'; import { TimeRange, TimeOptions, TimeOption } from '../../types/time'; -import { Moment } from 'moment'; import { TimePickerCalendar } from './TimePickerCalendar'; import { TimePickerInput } from './TimePickerInput'; import { mapTimeOptionToTimeRange } from './time'; import { Timezone } from '../../utils/datemath'; +import { DateTime } from '../../utils/moment_wrapper'; export interface Props { value: TimeRange; @@ -42,13 +42,13 @@ export class TimePickerPopover extends Component { }); }; - onFromCalendarChanged = (value: Moment) => { + onFromCalendarChanged = (value: DateTime) => { this.setState({ value: { ...this.state.value, raw: { ...this.state.value.raw, from: value } }, }); }; - onToCalendarChanged = (value: Moment) => { + onToCalendarChanged = (value: DateTime) => { this.setState({ value: { ...this.state.value, raw: { ...this.state.value.raw, to: value } }, }); diff --git a/packages/grafana-ui/src/components/TimePicker/time.ts b/packages/grafana-ui/src/components/TimePicker/time.ts index ca9303a8303..f697456eeb3 100644 --- a/packages/grafana-ui/src/components/TimePicker/time.ts +++ b/packages/grafana-ui/src/components/TimePicker/time.ts @@ -1,39 +1,39 @@ -import moment, { Moment } from 'moment'; import { TimeOption, TimeRange, TIME_FORMAT } from '../../types/time'; import { describeTimeRange } from '../../utils/rangeutil'; import * as dateMath from '../../utils/datemath'; +import { dateTime, DateTime, toUtc } from '../../utils/moment_wrapper'; export const mapTimeOptionToTimeRange = ( timeOption: TimeOption, isTimezoneUtc: boolean, timezone?: dateMath.Timezone ): TimeRange => { - const fromMoment = stringToMoment(timeOption.from, isTimezoneUtc, false, timezone); - const toMoment = stringToMoment(timeOption.to, isTimezoneUtc, true, timezone); + const fromMoment = stringToDateTimeType(timeOption.from, isTimezoneUtc, false, timezone); + const toMoment = stringToDateTimeType(timeOption.to, isTimezoneUtc, true, timezone); return { from: fromMoment, to: toMoment, raw: { from: timeOption.from, to: timeOption.to } }; }; -export const stringToMoment = ( +export const stringToDateTimeType = ( value: string, isTimezoneUtc: boolean, roundUp?: boolean, timezone?: dateMath.Timezone -): Moment => { +): DateTime => { if (value.indexOf('now') !== -1) { if (!dateMath.isValid(value)) { - return moment(); + return dateTime(); } const parsed = dateMath.parse(value, roundUp, timezone); - return parsed || moment(); + return parsed || dateTime(); } if (isTimezoneUtc) { - return moment.utc(value, TIME_FORMAT); + return toUtc(value, TIME_FORMAT); } - return moment(value, TIME_FORMAT); + return dateTime(value, TIME_FORMAT); }; export const mapTimeRangeToRangeString = (timeRange: TimeRange): string => { diff --git a/packages/grafana-ui/src/types/time.ts b/packages/grafana-ui/src/types/time.ts index d6c524ac19a..c7120776fac 100644 --- a/packages/grafana-ui/src/types/time.ts +++ b/packages/grafana-ui/src/types/time.ts @@ -1,13 +1,13 @@ -import { Moment } from 'moment'; +import { DateTime } from '../utils/moment_wrapper'; export interface RawTimeRange { - from: Moment | string; - to: Moment | string; + from: DateTime | string; + to: DateTime | string; } export interface TimeRange { - from: Moment; - to: Moment; + from: DateTime; + to: DateTime; raw: RawTimeRange; } @@ -47,6 +47,6 @@ export interface TimeOptions { [key: string]: TimeOption[]; } -export type TimeFragment = string | Moment; +export type TimeFragment = string | DateTime; export const TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; diff --git a/packages/grafana-ui/src/utils/datemath.test.ts b/packages/grafana-ui/src/utils/datemath.test.ts index 73407d55821..802fb0e0785 100644 --- a/packages/grafana-ui/src/utils/datemath.test.ts +++ b/packages/grafana-ui/src/utils/datemath.test.ts @@ -1,13 +1,13 @@ import sinon, { SinonFakeTimers } from 'sinon'; - -import * as dateMath from './datemath'; -import moment, { Moment, unitOfTime } from 'moment'; import each from 'lodash/each'; +import * as dateMath from './datemath'; +import { dateTime, DurationUnit, DateTime } from '../utils/moment_wrapper'; + describe('DateMath', () => { - const spans: unitOfTime.Base[] = ['s', 'm', 'h', 'd', 'w', 'M', 'y']; + const spans: DurationUnit[] = ['s', 'm', 'h', 'd', 'w', 'M', 'y']; const anchor = '2014-01-01T06:06:06.666Z'; - const unix = moment(anchor).valueOf(); + const unix = dateTime(anchor).valueOf(); const format = 'YYYY-MM-DDTHH:mm:ss.SSSZ'; let clock: SinonFakeTimers; @@ -55,13 +55,13 @@ describe('DateMath', () => { }); describe('subtraction', () => { - let now: Moment; - let anchored: Moment; + let now: DateTime; + let anchored: DateTime; beforeEach(() => { clock = sinon.useFakeTimers(unix); - now = moment(); - anchored = moment(anchor); + now = dateTime(); + anchored = dateTime(anchor); }); each(spans, span => { @@ -83,11 +83,11 @@ describe('DateMath', () => { }); describe('rounding', () => { - let now: Moment; + let now: DateTime; beforeEach(() => { clock = sinon.useFakeTimers(unix); - now = moment(); + now = dateTime(); }); each(spans, span => { @@ -116,17 +116,17 @@ describe('DateMath', () => { describe('relative time to date parsing', () => { it('should handle negative time', () => { - const date = dateMath.parseDateMath('-2d', moment([2014, 1, 5])); - expect(date!.valueOf()).toEqual(moment([2014, 1, 3]).valueOf()); + const date = dateMath.parseDateMath('-2d', dateTime([2014, 1, 5])); + expect(date!.valueOf()).toEqual(dateTime([2014, 1, 3]).valueOf()); }); it('should handle multiple math expressions', () => { - const date = dateMath.parseDateMath('-2d-6h', moment([2014, 1, 5])); - expect(date!.valueOf()).toEqual(moment([2014, 1, 2, 18]).valueOf()); + const date = dateMath.parseDateMath('-2d-6h', dateTime([2014, 1, 5])); + expect(date!.valueOf()).toEqual(dateTime([2014, 1, 2, 18]).valueOf()); }); it('should return false when invalid expression', () => { - const date = dateMath.parseDateMath('2', moment([2014, 1, 5])); + const date = dateMath.parseDateMath('2', dateTime([2014, 1, 5])); expect(date).toEqual(undefined); }); }); diff --git a/packages/grafana-ui/src/utils/datemath.ts b/packages/grafana-ui/src/utils/datemath.ts index af9719a73a3..6ab7b61ec66 100644 --- a/packages/grafana-ui/src/utils/datemath.ts +++ b/packages/grafana-ui/src/utils/datemath.ts @@ -1,8 +1,8 @@ import includes from 'lodash/includes'; import isDate from 'lodash/isDate'; -import moment, { unitOfTime } from 'moment'; +import { DateTime, dateTime, toUtc, ISO_8601, isDateTime, DurationUnit } from '../utils/moment_wrapper'; -const units: unitOfTime.Base[] = ['y', 'M', 'w', 'd', 'h', 'm', 's']; +const units: DurationUnit[] = ['y', 'M', 'w', 'd', 'h', 'm', 's']; export type Timezone = 'utc'; @@ -13,21 +13,17 @@ export type Timezone = 'utc'; * @param roundUp See parseDateMath function. * @param timezone Only string 'utc' is acceptable here, for anything else, local timezone is used. */ -export function parse( - text: string | moment.Moment | Date, - roundUp?: boolean, - timezone?: Timezone -): moment.Moment | undefined { +export function parse(text: string | DateTime | Date, roundUp?: boolean, timezone?: Timezone): DateTime | undefined { if (!text) { return undefined; } if (typeof text !== 'string') { - if (moment.isMoment(text)) { + if (isDateTime(text)) { return text; } if (isDate(text)) { - return moment(text); + return dateTime(text); } // We got some non string which is not a moment nor Date. TS should be able to check for that but not always. return undefined; @@ -39,9 +35,9 @@ export function parse( if (text.substring(0, 3) === 'now') { if (timezone === 'utc') { - time = moment.utc(); + time = toUtc(); } else { - time = moment(); + time = dateTime(); } mathString = text.substring('now'.length); } else { @@ -54,7 +50,7 @@ export function parse( mathString = text.substring(index + 2); } // We're going to just require ISO8601 timestamps, k? - time = moment(parseString, moment.ISO_8601); + time = dateTime(parseString, ISO_8601); } if (!mathString.length) { @@ -70,13 +66,13 @@ export function parse( * by parse function. See parse function to see what is considered acceptable. * @param text */ -export function isValid(text: string | moment.Moment): boolean { +export function isValid(text: string | DateTime): boolean { const date = parse(text); if (!date) { return false; } - if (moment.isMoment(date)) { + if (isDateTime(date)) { return date.isValid(); } @@ -90,7 +86,7 @@ export function isValid(text: string | moment.Moment): boolean { * @param roundUp If true it will round the time to endOf time unit, otherwise to startOf time unit. */ // TODO: Had to revert Andrejs `time: moment.Moment` to `time: any` -export function parseDateMath(mathString: string, time: any, roundUp?: boolean): moment.Moment | undefined { +export function parseDateMath(mathString: string, time: any, roundUp?: boolean): DateTime | undefined { const dateTime = time; let i = 0; const len = mathString.length; diff --git a/packages/grafana-ui/src/utils/displayValue.ts b/packages/grafana-ui/src/utils/displayValue.ts index 7c3a6e07034..59a04fefc2b 100644 --- a/packages/grafana-ui/src/utils/displayValue.ts +++ b/packages/grafana-ui/src/utils/displayValue.ts @@ -1,6 +1,5 @@ // Libraries import _ from 'lodash'; -import moment from 'moment'; // Utils import { getValueFormat } from './valueFormats/valueFormats'; @@ -18,6 +17,7 @@ import { DecimalCount, Field, } from '../types'; +import { DateTime, dateTime } from './moment_wrapper'; export type DisplayProcessor = (value: any) => DisplayValue; @@ -91,18 +91,18 @@ export function getDisplayProcessor(options?: DisplayValueOptions): DisplayProce return toStringProcessor; } -function toMoment(value: any, numeric: number, format: string): moment.Moment { +function toMoment(value: any, numeric: number, format: string): DateTime { if (!isNaN(numeric)) { - const v = moment(numeric); + const v = dateTime(numeric); if (v.isValid()) { return v; } } - const v = moment(value, format); + const v = dateTime(value, format); if (v.isValid) { return v; } - return moment(value); // moment will try to parse the format + return dateTime(value); // moment will try to parse the format } /** Will return any value as a number or NaN */ diff --git a/packages/grafana-ui/src/utils/index.ts b/packages/grafana-ui/src/utils/index.ts index d3b11d3e207..8a885736468 100644 --- a/packages/grafana-ui/src/utils/index.ts +++ b/packages/grafana-ui/src/utils/index.ts @@ -16,6 +16,7 @@ export * from './validate'; export { getFlotPairs } from './flotPairs'; export * from './object'; export * from './fieldCache'; +export * from './moment_wrapper'; // Names are too general to export // rangeutils, datemath diff --git a/packages/grafana-ui/src/utils/moment_wrapper.ts b/packages/grafana-ui/src/utils/moment_wrapper.ts new file mode 100644 index 00000000000..62b1e5b5c6e --- /dev/null +++ b/packages/grafana-ui/src/utils/moment_wrapper.ts @@ -0,0 +1,89 @@ +/* tslint:disable:import-blacklist ban ban-types */ +import moment, { MomentInput, DurationInputArg1 } from 'moment'; + +export interface DateTimeBuiltinFormat { + __momentBuiltinFormatBrand: any; +} +export const ISO_8601: DateTimeBuiltinFormat = moment.ISO_8601; +export type DateTimeInput = Date | string | number | Array | DateTime; // null | undefined +export type FormatInput = string | DateTimeBuiltinFormat | undefined; +export type DurationInput = string | number | DateTimeDuration; +export type DurationUnit = + | 'year' + | 'years' + | 'y' + | 'month' + | 'months' + | 'M' + | 'week' + | 'weeks' + | 'w' + | 'day' + | 'days' + | 'd' + | 'hour' + | 'hours' + | 'h' + | 'minute' + | 'minutes' + | 'm' + | 'second' + | 'seconds' + | 's' + | 'millisecond' + | 'milliseconds' + | 'ms' + | 'quarter' + | 'quarters' + | 'Q'; + +export interface DateTimeLocale { + firstDayOfWeek: () => number; +} + +export interface DateTimeDuration { + asHours: () => number; +} + +export interface DateTime extends Object { + add: (amount?: DateTimeInput, unit?: DurationUnit) => DateTime; + endOf: (unitOfTime: DurationUnit) => DateTime; + format: (formatInput?: FormatInput) => string; + fromNow: (withoutSuffix?: boolean) => string; + from: (formaInput: DateTimeInput) => string; + isSame: (input?: DateTimeInput, granularity?: DurationUnit) => boolean; + isValid: () => boolean; + local: () => DateTime; + locale: (locale: string) => DateTime; + startOf: (unitOfTime: DurationUnit) => DateTime; + subtract: (amount?: DateTimeInput, unit?: DurationUnit) => DateTime; + toDate: () => Date; + toISOString: () => string; + valueOf: () => number; + unix: () => number; + utc: () => DateTime; +} + +export const setLocale = (language: string) => { + moment.locale(language); +}; + +export const getLocaleData = (): DateTimeLocale => { + return moment.localeData(); +}; + +export const isDateTime = (value: any): value is DateTime => { + return moment.isMoment(value); +}; + +export const toUtc = (input?: DateTimeInput, formatInput?: FormatInput): DateTime => { + return moment.utc(input as MomentInput, formatInput) as DateTime; +}; + +export const toDuration = (input?: DurationInput, unit?: DurationUnit): DateTimeDuration => { + return moment.duration(input as DurationInputArg1, unit) as DateTimeDuration; +}; + +export const dateTime = (input?: DateTimeInput, formatInput?: FormatInput): DateTime => { + return moment(input as MomentInput, formatInput) as DateTime; +}; diff --git a/packages/grafana-ui/src/utils/processSeriesData.test.ts b/packages/grafana-ui/src/utils/processSeriesData.test.ts index 03b1a889db2..96afa79aa8c 100644 --- a/packages/grafana-ui/src/utils/processSeriesData.test.ts +++ b/packages/grafana-ui/src/utils/processSeriesData.test.ts @@ -7,7 +7,7 @@ import { guessFieldTypeFromValue, } from './processSeriesData'; import { FieldType, TimeSeries } from '../types/data'; -import moment from 'moment'; +import { dateTime } from './moment_wrapper'; describe('toSeriesData', () => { it('converts timeseries to series', () => { @@ -45,7 +45,7 @@ describe('toSeriesData', () => { expect(guessFieldTypeFromValue(true)).toBe(FieldType.boolean); expect(guessFieldTypeFromValue(false)).toBe(FieldType.boolean); expect(guessFieldTypeFromValue(new Date())).toBe(FieldType.time); - expect(guessFieldTypeFromValue(moment())).toBe(FieldType.time); + expect(guessFieldTypeFromValue(dateTime())).toBe(FieldType.time); }); it('Guess Colum Types from strings', () => { diff --git a/packages/grafana-ui/src/utils/processSeriesData.ts b/packages/grafana-ui/src/utils/processSeriesData.ts index 0a8d420fdaa..f07baeaaf6e 100644 --- a/packages/grafana-ui/src/utils/processSeriesData.ts +++ b/packages/grafana-ui/src/utils/processSeriesData.ts @@ -2,10 +2,10 @@ import isNumber from 'lodash/isNumber'; import isString from 'lodash/isString'; import isBoolean from 'lodash/isBoolean'; -import moment from 'moment'; // Types import { SeriesData, Field, TimeSeries, FieldType, TableData } from '../types/index'; +import { isDateTime } from './moment_wrapper'; function convertTableToSeriesData(table: TableData): SeriesData { return { @@ -73,7 +73,7 @@ export function guessFieldTypeFromValue(v: any): FieldType { return FieldType.boolean; } - if (v instanceof Date || v instanceof moment) { + if (v instanceof Date || isDateTime(v)) { return FieldType.time; } diff --git a/packages/grafana-ui/src/utils/rangeutil.ts b/packages/grafana-ui/src/utils/rangeutil.ts index 16f27914cf4..bcc27ecfd8e 100644 --- a/packages/grafana-ui/src/utils/rangeutil.ts +++ b/packages/grafana-ui/src/utils/rangeutil.ts @@ -1,10 +1,10 @@ // @ts-ignore import _ from 'lodash'; -import moment from 'moment'; import { RawTimeRange } from '../types/time'; import * as dateMath from './datemath'; +import { isDateTime, DateTime } from '../utils/moment_wrapper'; const spans: { [key: string]: { display: string; section?: number } } = { s: { display: 'second' }, @@ -85,7 +85,7 @@ export function getRelativeTimesList(timepickerSettings: any, currentDisplay: an return groups; } -function formatDate(date: any) { +function formatDate(date: DateTime) { return date.format(absoluteFormat); } @@ -139,16 +139,16 @@ export function describeTimeRange(range: RawTimeRange): string { return option.display; } - if (moment.isMoment(range.from) && moment.isMoment(range.to)) { + if (isDateTime(range.from) && isDateTime(range.to)) { return formatDate(range.from) + ' to ' + formatDate(range.to); } - if (moment.isMoment(range.from)) { + if (isDateTime(range.from)) { const toMoment = dateMath.parse(range.to, true); return toMoment ? formatDate(range.from) + ' to ' + toMoment.fromNow() : ''; } - if (moment.isMoment(range.to)) { + if (isDateTime(range.to)) { const from = dateMath.parse(range.from, false); return from ? from.fromNow() + ' to ' + formatDate(range.to) : ''; } diff --git a/packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.test.ts b/packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.test.ts index cf69a1d433a..f800d2b75fd 100644 --- a/packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.test.ts +++ b/packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.test.ts @@ -1,4 +1,3 @@ -import moment from 'moment'; import { dateTimeAsIso, dateTimeAsUS, @@ -9,11 +8,12 @@ import { toDurationInMilliseconds, toDurationInSeconds, } from './dateTimeFormatters'; +import { toUtc, dateTime } from '../moment_wrapper'; describe('date time formats', () => { const epoch = 1505634997920; - const utcTime = moment.utc(epoch); - const browserTime = moment(epoch); + const utcTime = toUtc(epoch); + const browserTime = dateTime(epoch); it('should format as iso date', () => { const expected = browserTime.format('YYYY-MM-DD HH:mm:ss'); @@ -28,14 +28,14 @@ describe('date time formats', () => { }); it('should format as iso date and skip date when today', () => { - const now = moment(); + const now = dateTime(); const expected = now.format('HH:mm:ss'); const actual = dateTimeAsIso(now.valueOf(), 0, 0, false); expect(actual).toBe(expected); }); it('should format as iso date (in UTC) and skip date when today', () => { - const now = moment.utc(); + const now = toUtc(); const expected = now.format('HH:mm:ss'); const actual = dateTimeAsIso(now.valueOf(), 0, 0, true); expect(actual).toBe(expected); @@ -54,42 +54,42 @@ describe('date time formats', () => { }); it('should format as US date and skip date when today', () => { - const now = moment(); + const now = dateTime(); const expected = now.format('h:mm:ss a'); const actual = dateTimeAsUS(now.valueOf(), 0, 0, false); expect(actual).toBe(expected); }); it('should format as US date (in UTC) and skip date when today', () => { - const now = moment.utc(); + const now = toUtc(); const expected = now.format('h:mm:ss a'); const actual = dateTimeAsUS(now.valueOf(), 0, 0, true); expect(actual).toBe(expected); }); it('should format as from now with days', () => { - const daysAgo = moment().add(-7, 'd'); + const daysAgo = dateTime().add(-7, 'd'); const expected = '7 days ago'; const actual = dateTimeFromNow(daysAgo.valueOf(), 0, 0, false); expect(actual).toBe(expected); }); it('should format as from now with days (in UTC)', () => { - const daysAgo = moment.utc().add(-7, 'd'); + const daysAgo = toUtc().add(-7, 'd'); const expected = '7 days ago'; const actual = dateTimeFromNow(daysAgo.valueOf(), 0, 0, true); expect(actual).toBe(expected); }); it('should format as from now with minutes', () => { - const daysAgo = moment().add(-2, 'm'); + const daysAgo = dateTime().add(-2, 'm'); const expected = '2 minutes ago'; const actual = dateTimeFromNow(daysAgo.valueOf(), 0, 0, false); expect(actual).toBe(expected); }); it('should format as from now with minutes (in UTC)', () => { - const daysAgo = moment.utc().add(-2, 'm'); + const daysAgo = toUtc().add(-2, 'm'); const expected = '2 minutes ago'; const actual = dateTimeFromNow(daysAgo.valueOf(), 0, 0, true); expect(actual).toBe(expected); diff --git a/packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.ts b/packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.ts index bad77191fb5..2c2ab346816 100644 --- a/packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.ts +++ b/packages/grafana-ui/src/utils/valueFormats/dateTimeFormatters.ts @@ -1,6 +1,6 @@ import { toFixed, toFixedScaled } from './valueFormats'; import { DecimalCount } from '../../types'; -import moment from 'moment'; +import { toUtc, toDuration as duration, dateTime } from '../moment_wrapper'; interface IntervalsInSeconds { [interval: string]: number; @@ -237,7 +237,7 @@ export function toClock(size: number, decimals?: DecimalCount) { // < 1 second if (size < 1000) { - return moment.utc(size).format('SSS\\m\\s'); + return toUtc(size).format('SSS\\m\\s'); } // < 1 minute @@ -246,7 +246,7 @@ export function toClock(size: number, decimals?: DecimalCount) { if (decimals === 0) { format = 'ss\\s'; } - return moment.utc(size).format(format); + return toUtc(size).format(format); } // < 1 hour @@ -257,12 +257,12 @@ export function toClock(size: number, decimals?: DecimalCount) { } else if (decimals === 1) { format = 'mm\\m:ss\\s'; } - return moment.utc(size).format(format); + return toUtc(size).format(format); } let format = 'mm\\m:ss\\s:SSS\\m\\s'; - const hours = `${('0' + Math.floor(moment.duration(size, 'milliseconds').asHours())).slice(-2)}h`; + const hours = `${('0' + Math.floor(duration(size, 'milliseconds').asHours())).slice(-2)}h`; if (decimals === 0) { format = ''; @@ -272,7 +272,7 @@ export function toClock(size: number, decimals?: DecimalCount) { format = 'mm\\m:ss\\s'; } - return format ? `${hours}:${moment.utc(size).format(format)}` : hours; + return format ? `${hours}:${toUtc(size).format(format)}` : hours; } export function toDurationInMilliseconds(size: number, decimals: DecimalCount) { @@ -307,24 +307,24 @@ export function toClockSeconds(size: number, decimals: DecimalCount) { } export function dateTimeAsIso(value: number, decimals: DecimalCount, scaledDecimals: DecimalCount, isUtc?: boolean) { - const time = isUtc ? moment.utc(value) : moment(value); + const time = isUtc ? toUtc(value) : dateTime(value); - if (moment().isSame(value, 'day')) { + if (dateTime().isSame(value, 'day')) { return time.format('HH:mm:ss'); } return time.format('YYYY-MM-DD HH:mm:ss'); } export function dateTimeAsUS(value: number, decimals: DecimalCount, scaledDecimals: DecimalCount, isUtc?: boolean) { - const time = isUtc ? moment.utc(value) : moment(value); + const time = isUtc ? toUtc(value) : dateTime(value); - if (moment().isSame(value, 'day')) { + if (dateTime().isSame(value, 'day')) { return time.format('h:mm:ss a'); } return time.format('MM/DD/YYYY h:mm:ss a'); } export function dateTimeFromNow(value: number, decimals: DecimalCount, scaledDecimals: DecimalCount, isUtc?: boolean) { - const time = isUtc ? moment.utc(value) : moment(value); + const time = isUtc ? toUtc(value) : dateTime(value); return time.fromNow(); } diff --git a/packages/grafana-ui/tslint.json b/packages/grafana-ui/tslint.json index 47cbd69e846..937aa29800e 100644 --- a/packages/grafana-ui/tslint.json +++ b/packages/grafana-ui/tslint.json @@ -1,6 +1,6 @@ { "extends": "../../tslint.json", "rules": { - "import-blacklist": [true, ["^@grafana/ui.*"]] + "import-blacklist": [true, "moment", ["^@grafana/ui.*"]] } } diff --git a/public/app/app.ts b/public/app/app.ts index c72d17bbf5a..9f95634330d 100644 --- a/public/app/app.ts +++ b/public/app/app.ts @@ -19,7 +19,6 @@ import angular from 'angular'; import config from 'app/core/config'; // @ts-ignore ignoring this for now, otherwise we would have to extend _ interface with move import _ from 'lodash'; -import moment from 'moment'; import { addClassIfNoOverlayScrollbar } from 'app/core/utils/scrollbar'; import { importPluginModule } from 'app/features/plugins/plugin_loader'; @@ -36,6 +35,7 @@ import { setupAngularRoutes } from 'app/routes/routes'; import 'app/routes/GrafanaCtrl'; import 'app/features/all'; +import { setLocale } from '@grafana/ui/src/utils/moment_wrapper'; // import symlinked extensions const extensionsIndex = (require as any).context('.', true, /extensions\/index.ts/); @@ -68,7 +68,7 @@ export class GrafanaApp { init() { const app = angular.module('grafana', []); - moment.locale(config.bootData.user.locale); + setLocale(config.bootData.user.locale); app.config( ( diff --git a/public/app/core/filters/filters.ts b/public/app/core/filters/filters.ts index 22e1f9a7983..1176395d09a 100644 --- a/public/app/core/filters/filters.ts +++ b/public/app/core/filters/filters.ts @@ -1,8 +1,8 @@ import _ from 'lodash'; import angular from 'angular'; -import moment from 'moment'; import coreModule from '../core_module'; import { TemplateSrv } from 'app/features/templating/template_srv'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; coreModule.filter('stringSort', () => { return (input: any) => { @@ -33,9 +33,9 @@ coreModule.filter('moment', () => { return (date: string, mode: string) => { switch (mode) { case 'ago': - return moment(date).fromNow(); + return dateTime(date).fromNow(); } - return moment(date).fromNow(); + return dateTime(date).fromNow(); }; }); diff --git a/public/app/core/logs_model.ts b/public/app/core/logs_model.ts index 03420f80299..ecea101872a 100644 --- a/public/app/core/logs_model.ts +++ b/public/app/core/logs_model.ts @@ -1,5 +1,4 @@ import _ from 'lodash'; -import moment from 'moment'; import ansicolor from 'vendor/ansicolor/ansicolor'; import { @@ -17,6 +16,7 @@ import { } from '@grafana/ui'; import { getThemeColor } from 'app/core/utils/colors'; import { hasAnsiCodes } from 'app/core/utils/text'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export const LogLevelColor = { [LogLevel.critical]: colors[7], @@ -435,7 +435,7 @@ export function processLogSeriesRow( const ts = row[timeFieldIndex]; const stringFieldIndex = fieldCache.getFirstFieldOfType(FieldType.string).index; const message = row[stringFieldIndex]; - const time = moment(ts); + const time = dateTime(ts); const timeEpochMs = time.valueOf(); const timeFromNow = time.fromNow(); const timeLocal = time.format('YYYY-MM-DD HH:mm:ss'); diff --git a/public/app/core/specs/rangeutil.test.ts b/public/app/core/specs/rangeutil.test.ts index 0094b714cd9..d23bbf9f0eb 100644 --- a/public/app/core/specs/rangeutil.test.ts +++ b/public/app/core/specs/rangeutil.test.ts @@ -1,6 +1,6 @@ import * as rangeUtil from '@grafana/ui/src/utils/rangeutil'; import _ from 'lodash'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('rangeUtil', () => { describe('Can get range grouped list of ranges', () => { @@ -69,7 +69,7 @@ describe('rangeUtil', () => { it('Date range with absolute to now', () => { const text = rangeUtil.describeTimeRange({ - from: moment([2014, 10, 10, 2, 3, 4]), + from: dateTime([2014, 10, 10, 2, 3, 4]), to: 'now', }); expect(text).toBe('Nov 10, 2014 02:03:04 to a few seconds ago'); @@ -77,7 +77,7 @@ describe('rangeUtil', () => { it('Date range with absolute to relative', () => { const text = rangeUtil.describeTimeRange({ - from: moment([2014, 10, 10, 2, 3, 4]), + from: dateTime([2014, 10, 10, 2, 3, 4]), to: 'now-1d', }); expect(text).toBe('Nov 10, 2014 02:03:04 to a day ago'); @@ -86,7 +86,7 @@ describe('rangeUtil', () => { it('Date range with relative to absolute', () => { const text = rangeUtil.describeTimeRange({ from: 'now-7d', - to: moment([2014, 10, 10, 2, 3, 4]), + to: dateTime([2014, 10, 10, 2, 3, 4]), }); expect(text).toBe('7 days ago to Nov 10, 2014 02:03:04'); }); diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts index 5df42ad92d9..d507b6c1a82 100644 --- a/public/app/core/utils/explore.ts +++ b/public/app/core/utils/explore.ts @@ -1,6 +1,5 @@ // Libraries import _ from 'lodash'; -import moment, { Moment } from 'moment'; // Services & Utils import * as dateMath from '@grafana/ui/src/utils/datemath'; @@ -21,6 +20,7 @@ import { DataSourceApi, toSeriesData, guessFieldTypes, + TimeFragment, } from '@grafana/ui'; import TimeSeries from 'app/core/time_series2'; import { @@ -33,6 +33,7 @@ import { ResultGetter, } from 'app/types/explore'; import { LogsDedupStrategy, seriesDataToLogsModel } from 'app/core/logs_model'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; export const DEFAULT_RANGE = { from: 'now-6h', @@ -401,7 +402,7 @@ export const getTimeRange = (timeZone: TimeZone, rawRange: RawTimeRange): TimeRa }; }; -const parseRawTime = (value): Moment | string => { +const parseRawTime = (value): TimeFragment => { if (value === null) { return null; } @@ -410,19 +411,19 @@ const parseRawTime = (value): Moment | string => { return value; } if (value.length === 8) { - return moment.utc(value, 'YYYYMMDD'); + return toUtc(value, 'YYYYMMDD'); } if (value.length === 15) { - return moment.utc(value, 'YYYYMMDDTHHmmss'); + return toUtc(value, 'YYYYMMDDTHHmmss'); } // Backward compatibility if (value.length === 19) { - return moment.utc(value, 'YYYY-MM-DD HH:mm:ss'); + return toUtc(value, 'YYYY-MM-DD HH:mm:ss'); } if (!isNaN(value)) { const epoch = parseInt(value, 10); - return moment.utc(epoch); + return toUtc(epoch); } return null; diff --git a/public/app/core/utils/file_export.ts b/public/app/core/utils/file_export.ts index c59d646839f..6d341b5582e 100644 --- a/public/app/core/utils/file_export.ts +++ b/public/app/core/utils/file_export.ts @@ -1,7 +1,7 @@ import { isBoolean, isNumber, sortedUniq, sortedIndexOf, unescape as htmlUnescaped } from 'lodash'; -import moment from 'moment'; import { saveAs } from 'file-saver'; import { isNullOrUndefined } from 'util'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; const DEFAULT_DATETIME_FORMAT = 'YYYY-MM-DDTHH:mm:ssZ'; const POINT_TIME_INDEX = 1; @@ -61,7 +61,7 @@ export function convertSeriesListToCsv(seriesList, dateTimeFormat = DEFAULT_DATE text += formatRow( [ seriesList[seriesIndex].alias, - moment(seriesList[seriesIndex].datapoints[i][POINT_TIME_INDEX]).format(dateTimeFormat), + dateTime(seriesList[seriesIndex].datapoints[i][POINT_TIME_INDEX]).format(dateTimeFormat), seriesList[seriesIndex].datapoints[i][POINT_VALUE_INDEX], ], i < seriesList[seriesIndex].datapoints.length - 1 || seriesIndex < seriesList.length - 1 @@ -92,7 +92,7 @@ export function convertSeriesListToCsvColumns(seriesList, dateTimeFormat = DEFAU // make text for (let i = 0; i < extendedDatapointsList[0].length; i += 1) { - const timestamp = moment(extendedDatapointsList[0][i][POINT_TIME_INDEX]).format(dateTimeFormat); + const timestamp = dateTime(extendedDatapointsList[0][i][POINT_TIME_INDEX]).format(dateTimeFormat); text += formatRow( [timestamp].concat( extendedDatapointsList.map(datapoints => { diff --git a/public/app/features/alerting/state/reducers.ts b/public/app/features/alerting/state/reducers.ts index f956dc34005..24007600938 100644 --- a/public/app/features/alerting/state/reducers.ts +++ b/public/app/features/alerting/state/reducers.ts @@ -1,7 +1,7 @@ -import moment from 'moment'; import { AlertRuleDTO, AlertRule, AlertRulesState } from 'app/types'; import { Action, ActionTypes } from './actions'; import alertDef from './alertDef'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export const initialState: AlertRulesState = { items: [], searchQuery: '', isLoading: false }; @@ -10,7 +10,7 @@ function convertToAlertRule(rule, state): AlertRule { rule.stateText = stateModel.text; rule.stateIcon = stateModel.iconClass; rule.stateClass = stateModel.stateClass; - rule.stateAge = moment(rule.newStateDate) + rule.stateAge = dateTime(rule.newStateDate) .fromNow() .replace(' ago', ''); diff --git a/public/app/features/annotations/event_editor.ts b/public/app/features/annotations/event_editor.ts index a6970790bb3..3cec5f13d7a 100644 --- a/public/app/features/annotations/event_editor.ts +++ b/public/app/features/annotations/event_editor.ts @@ -1,8 +1,8 @@ import _ from 'lodash'; -import moment from 'moment'; import { coreModule } from 'app/core/core'; import { MetricsPanelCtrl } from 'app/plugins/sdk'; import { AnnotationEvent } from '@grafana/ui'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export class EventEditorCtrl { panelCtrl: MetricsPanelCtrl; @@ -86,7 +86,7 @@ export class EventEditorCtrl { function tryEpochToMoment(timestamp) { if (timestamp && _.isNumber(timestamp)) { const epoch = Number(timestamp); - return moment(epoch); + return dateTime(epoch); } else { return timestamp; } diff --git a/public/app/features/dashboard/components/ShareModal/ShareModalCtrl.ts b/public/app/features/dashboard/components/ShareModal/ShareModalCtrl.ts index b4ce25485b8..9d3c36ee2bc 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareModalCtrl.ts +++ b/public/app/features/dashboard/components/ShareModal/ShareModalCtrl.ts @@ -1,6 +1,6 @@ import angular from 'angular'; import config from 'app/core/config'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; /** @ngInject */ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv, templateSrv, linkSrv) { @@ -93,7 +93,7 @@ export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv, // This function will try to return the proper full name of the local timezone // Chrome does not handle the timezone offset (but phantomjs does) $scope.getLocalTimeZone = () => { - const utcOffset = '&tz=UTC' + encodeURIComponent(moment().format('Z')); + const utcOffset = '&tz=UTC' + encodeURIComponent(dateTime().format('Z')); // Older browser does not the internationalization API if (!(window as any).Intl) { diff --git a/public/app/features/dashboard/components/TimePicker/TimePickerCtrl.ts b/public/app/features/dashboard/components/TimePicker/TimePickerCtrl.ts index a710bded593..f1d626e9e34 100644 --- a/public/app/features/dashboard/components/TimePicker/TimePickerCtrl.ts +++ b/public/app/features/dashboard/components/TimePicker/TimePickerCtrl.ts @@ -1,6 +1,5 @@ import _ from 'lodash'; import angular from 'angular'; -import moment from 'moment'; import * as rangeUtil from '@grafana/ui/src/utils/rangeutil'; @@ -38,7 +37,7 @@ export class TimePickerCtrl { // init options this.panel = this.dashboard.timepicker; _.defaults(this.panel, TimePickerCtrl.defaults); - this.firstDayOfWeek = moment.localeData().firstDayOfWeek(); + this.firstDayOfWeek = getLocaleData().firstDayOfWeek(); // init time stuff this.onRefresh(); @@ -51,10 +50,10 @@ export class TimePickerCtrl { if (!this.dashboard.isTimezoneUtc()) { time.from.local(); time.to.local(); - if (moment.isMoment(timeRaw.from)) { + if (isDateTime(timeRaw.from)) { timeRaw.from.local(); } - if (moment.isMoment(timeRaw.to)) { + if (isDateTime(timeRaw.to)) { timeRaw.to.local(); } this.isUtc = false; @@ -67,7 +66,7 @@ export class TimePickerCtrl { this.tooltip = this.dashboard.formatDate(time.from) + '
to
'; this.tooltip += this.dashboard.formatDate(time.to); this.timeRaw = timeRaw; - this.isAbsolute = moment.isMoment(this.timeRaw.to); + this.isAbsolute = isDateTime(this.timeRaw.to); } zoom(factor) { @@ -94,7 +93,7 @@ export class TimePickerCtrl { from = range.from.valueOf(); } - this.timeSrv.setTime({ from: moment.utc(from), to: moment.utc(to) }); + this.timeSrv.setTime({ from: toUtc(from), to: toUtc(to) }); } openDropdown() { @@ -141,7 +140,7 @@ export class TimePickerCtrl { } getAbsoluteMomentForTimezone(jsDate) { - return this.dashboard.isTimezoneUtc() ? moment(jsDate).utc() : moment(jsDate); + return this.dashboard.isTimezoneUtc() ? dateTime(jsDate).utc() : dateTime(jsDate); } setRelativeFilter(timespan) { @@ -186,4 +185,5 @@ angular.module('grafana.directives').directive('gfTimePickerSettings', settingsD angular.module('grafana.directives').directive('gfTimePicker', timePickerDirective); import { inputDateDirective } from './validation'; +import { toUtc, getLocaleData, isDateTime, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; angular.module('grafana.directives').directive('inputDatetime', inputDateDirective); diff --git a/public/app/features/dashboard/components/TimePicker/validation.ts b/public/app/features/dashboard/components/TimePicker/validation.ts index 7bf229441ec..a99409a0fb0 100644 --- a/public/app/features/dashboard/components/TimePicker/validation.ts +++ b/public/app/features/dashboard/components/TimePicker/validation.ts @@ -1,5 +1,5 @@ -import moment from 'moment'; import * as dateMath from '@grafana/ui/src/utils/datemath'; +import { toUtc, dateTime, isDateTime } from '@grafana/ui/src/utils/moment_wrapper'; export function inputDateDirective() { return { @@ -20,9 +20,9 @@ export function inputDateDirective() { let parsed; if ($scope.ctrl.isUtc) { - parsed = moment.utc(text, format); + parsed = toUtc(text, format); } else { - parsed = moment(text, format); + parsed = dateTime(text, format); } if (!parsed.isValid()) { @@ -35,7 +35,7 @@ export function inputDateDirective() { }; const toUser = currentValue => { - if (moment.isMoment(currentValue)) { + if (isDateTime(currentValue)) { return currentValue.format(format); } else { return currentValue; diff --git a/public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.ts b/public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.ts index 19795ffc564..cc918330a5e 100644 --- a/public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.ts +++ b/public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.ts @@ -1,10 +1,10 @@ import _ from 'lodash'; import angular from 'angular'; -import moment from 'moment'; import locationUtil from 'app/core/utils/location_util'; import { DashboardModel } from '../../state/DashboardModel'; import { HistoryListOpts, RevisionsModel, CalculateDiffOptions, HistorySrv } from './HistorySrv'; +import { dateTime, toUtc } from '@grafana/ui/src/utils/moment_wrapper'; export class HistoryListCtrl { appending: boolean; @@ -74,8 +74,8 @@ export class HistoryListCtrl { } formatBasicDate(date) { - const now = this.dashboard.timezone === 'browser' ? moment() : moment.utc(); - const then = this.dashboard.timezone === 'browser' ? moment(date) : moment.utc(date); + const now = this.dashboard.timezone === 'browser' ? dateTime() : toUtc(); + const then = this.dashboard.timezone === 'browser' ? dateTime(date) : toUtc(date); return then.from(now); } diff --git a/public/app/features/dashboard/services/DashboardLoaderSrv.ts b/public/app/features/dashboard/services/DashboardLoaderSrv.ts index 7cde345ee99..2d1c0b556b0 100644 --- a/public/app/features/dashboard/services/DashboardLoaderSrv.ts +++ b/public/app/features/dashboard/services/DashboardLoaderSrv.ts @@ -1,3 +1,4 @@ +/* tslint:disable:import-blacklist */ import angular from 'angular'; import moment from 'moment'; import _ from 'lodash'; diff --git a/public/app/features/dashboard/services/TimeSrv.test.ts b/public/app/features/dashboard/services/TimeSrv.test.ts index 8bb93fc3aec..c54bfddc140 100644 --- a/public/app/features/dashboard/services/TimeSrv.test.ts +++ b/public/app/features/dashboard/services/TimeSrv.test.ts @@ -1,6 +1,6 @@ -import moment from 'moment'; import { TimeSrv } from './TimeSrv'; import { ContextSrvStub } from 'test/specs/helpers'; +import { isDateTime, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('timeSrv', () => { const rootScope = { @@ -43,8 +43,8 @@ describe('timeSrv', () => { it('should return parsed when parse is true', () => { timeSrv.setTime({ from: 'now', to: 'now-1h' }); const time = timeSrv.timeRange(); - expect(moment.isMoment(time.from)).toBe(true); - expect(moment.isMoment(time.to)).toBe(true); + expect(isDateTime(time.from)).toBe(true); + expect(isDateTime(time.to)).toBe(true); }); }); @@ -164,8 +164,8 @@ describe('timeSrv', () => { it('should restore refresh after relative time range is set', () => { _dashboard.refresh = '10s'; timeSrv.setTime({ - from: moment([2011, 1, 1]), - to: moment([2015, 1, 1]), + from: dateTime([2011, 1, 1]), + to: dateTime([2015, 1, 1]), }); expect(_dashboard.refresh).toBe(false); timeSrv.setTime({ from: '2011-01-01', to: 'now' }); diff --git a/public/app/features/dashboard/services/TimeSrv.ts b/public/app/features/dashboard/services/TimeSrv.ts index d6f0e91940e..9c415b9aea5 100644 --- a/public/app/features/dashboard/services/TimeSrv.ts +++ b/public/app/features/dashboard/services/TimeSrv.ts @@ -1,5 +1,4 @@ // Libraries -import moment from 'moment'; import _ from 'lodash'; // Utils @@ -12,6 +11,7 @@ import { TimeRange, RawTimeRange } from '@grafana/ui'; import { ITimeoutService, ILocationService } from 'angular'; import { ContextSrv } from 'app/core/services/context_srv'; import { DashboardModel } from '../state/DashboardModel'; +import { toUtc, dateTime, isDateTime } from '@grafana/ui/src/utils/moment_wrapper'; export class TimeSrv { time: any; @@ -65,10 +65,10 @@ export class TimeSrv { private parseTime() { // when absolute time is saved in json it is turned to a string if (_.isString(this.time.from) && this.time.from.indexOf('Z') >= 0) { - this.time.from = moment(this.time.from).utc(); + this.time.from = dateTime(this.time.from).utc(); } if (_.isString(this.time.to) && this.time.to.indexOf('Z') >= 0) { - this.time.to = moment(this.time.to).utc(); + this.time.to = dateTime(this.time.to).utc(); } } @@ -77,15 +77,15 @@ export class TimeSrv { return value; } if (value.length === 8) { - return moment.utc(value, 'YYYYMMDD'); + return toUtc(value, 'YYYYMMDD'); } if (value.length === 15) { - return moment.utc(value, 'YYYYMMDDTHHmmss'); + return toUtc(value, 'YYYYMMDDTHHmmss'); } if (!isNaN(value)) { const epoch = parseInt(value, 10); - return moment.utc(epoch); + return toUtc(epoch); } return null; @@ -184,7 +184,7 @@ export class TimeSrv { _.extend(this.time, time); // disable refresh if zoom in or zoom out - if (moment.isMoment(time.to)) { + if (isDateTime(time.to)) { this.oldRefresh = this.dashboard.refresh || this.oldRefresh; this.setAutoRefresh(false); } else if (this.oldRefresh && this.oldRefresh !== this.dashboard.refresh) { @@ -207,10 +207,10 @@ export class TimeSrv { timeRangeForUrl() { const range = this.timeRange().raw; - if (moment.isMoment(range.from)) { + if (isDateTime(range.from)) { range.from = range.from.valueOf().toString(); } - if (moment.isMoment(range.to)) { + if (isDateTime(range.to)) { range.to = range.to.valueOf().toString(); } @@ -220,8 +220,8 @@ export class TimeSrv { timeRange(): TimeRange { // make copies if they are moment (do not want to return out internal moment, because they are mutable!) const raw = { - from: moment.isMoment(this.time.from) ? moment(this.time.from) : this.time.from, - to: moment.isMoment(this.time.to) ? moment(this.time.to) : this.time.to, + from: isDateTime(this.time.from) ? dateTime(this.time.from) : this.time.from, + to: isDateTime(this.time.to) ? dateTime(this.time.to) : this.time.to, }; const timezone = this.dashboard && this.dashboard.getTimezone(); @@ -242,7 +242,7 @@ export class TimeSrv { const to = center + (timespan * factor) / 2; const from = center - (timespan * factor) / 2; - this.setTime({ from: moment.utc(from), to: moment.utc(to) }); + this.setTime({ from: toUtc(from), to: toUtc(to) }); } } diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts index cfe4f536337..d5301e98cea 100644 --- a/public/app/features/dashboard/state/DashboardModel.ts +++ b/public/app/features/dashboard/state/DashboardModel.ts @@ -1,5 +1,4 @@ // Libaries -import moment, { MomentInput } from 'moment'; import _ from 'lodash'; // Constants @@ -16,6 +15,7 @@ import { PanelModel, GridPos } from './PanelModel'; import { DashboardMigrator } from './DashboardMigrator'; import { TimeRange } from '@grafana/ui/src'; import { UrlQueryValue, KIOSK_MODE_TV, DashboardMeta } from 'app/types'; +import { toUtc, DateTimeInput, dateTime, isDateTime } from '@grafana/ui/src/utils/moment_wrapper'; export interface CloneOptions { saveVariables?: boolean; @@ -698,12 +698,12 @@ export class DashboardModel { return newPanel; } - formatDate(date: MomentInput, format?: string) { - date = moment.isMoment(date) ? date : moment(date); + formatDate(date: DateTimeInput, format?: string) { + date = isDateTime(date) ? date : dateTime(date); format = format || 'YYYY-MM-DD HH:mm:ss'; const timezone = this.getTimezone(); - return timezone === 'browser' ? moment(date).format(format) : moment.utc(date).format(format); + return timezone === 'browser' ? dateTime(date).format(format) : toUtc(date).format(format); } destroy() { @@ -817,10 +817,10 @@ export class DashboardModel { return this.graphTooltip === 1; } - getRelativeTime(date: MomentInput) { - date = moment.isMoment(date) ? date : moment(date); + getRelativeTime(date: DateTimeInput) { + date = isDateTime(date) ? date : dateTime(date); - return this.timezone === 'browser' ? moment(date).fromNow() : moment.utc(date).fromNow(); + return this.timezone === 'browser' ? dateTime(date).fromNow() : toUtc(date).fromNow(); } isTimezoneUtc() { diff --git a/public/app/features/dashboard/state/PanelQueryRunner.test.ts b/public/app/features/dashboard/state/PanelQueryRunner.test.ts index 16cd2bc349b..4e9cba5100c 100644 --- a/public/app/features/dashboard/state/PanelQueryRunner.test.ts +++ b/public/app/features/dashboard/state/PanelQueryRunner.test.ts @@ -7,7 +7,7 @@ import { LoadingState, ScopedVars, } from '@grafana/ui/src/types'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; jest.mock('app/core/services/backend_srv'); @@ -68,8 +68,8 @@ function describeQueryRunnerScenario(description: string, scenarioFn: ScenarioFn widthPixels: ctx.widthPixels, maxDataPoints: ctx.maxDataPoints, timeRange: { - from: moment().subtract(1, 'days'), - to: moment(), + from: dateTime().subtract(1, 'days'), + to: dateTime(), raw: { from: '1h', to: 'now' }, }, panelId: 0, diff --git a/public/app/features/dashboard/utils/panel.test.ts b/public/app/features/dashboard/utils/panel.test.ts index e32b7d84d68..a05c54b2ab7 100644 --- a/public/app/features/dashboard/utils/panel.test.ts +++ b/public/app/features/dashboard/utils/panel.test.ts @@ -1,11 +1,11 @@ -import moment from 'moment'; import { TimeRange } from '@grafana/ui'; import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel'; import { advanceTo, clear } from 'jest-date-mock'; +import { dateTime, DateTime } from '@grafana/ui/src/utils/moment_wrapper'; const dashboardTimeRange: TimeRange = { - from: moment([2019, 1, 11, 12, 0]), - to: moment([2019, 1, 11, 18, 0]), + from: dateTime([2019, 1, 11, 12, 0]), + to: dateTime([2019, 1, 11, 18, 0]), raw: { from: 'now-6h', to: 'now', @@ -13,7 +13,7 @@ const dashboardTimeRange: TimeRange = { }; describe('applyPanelTimeOverrides', () => { - const fakeCurrentDate = moment([2019, 1, 11, 14, 0, 0]).toDate(); + const fakeCurrentDate = dateTime([2019, 1, 11, 14, 0, 0]).toDate(); beforeAll(() => { advanceTo(fakeCurrentDate); @@ -31,7 +31,7 @@ describe('applyPanelTimeOverrides', () => { // @ts-ignore: PanelModel type incositency const overrides = applyPanelTimeOverrides(panelModel, dashboardTimeRange); - expect(overrides.timeRange.from.toISOString()).toBe(moment([2019, 1, 11, 12]).toISOString()); + expect(overrides.timeRange.from.toISOString()).toBe(dateTime([2019, 1, 11, 12]).toISOString()); expect(overrides.timeRange.to.toISOString()).toBe(fakeCurrentDate.toISOString()); expect(overrides.timeRange.raw.from).toBe('now-2h'); expect(overrides.timeRange.raw.to).toBe('now'); @@ -42,16 +42,16 @@ describe('applyPanelTimeOverrides', () => { timeShift: '2h', }; - const expectedFromDate = moment([2019, 1, 11, 10, 0, 0]).toDate(); - const expectedToDate = moment([2019, 1, 11, 16, 0, 0]).toDate(); + const expectedFromDate = dateTime([2019, 1, 11, 10, 0, 0]).toDate(); + const expectedToDate = dateTime([2019, 1, 11, 16, 0, 0]).toDate(); // @ts-ignore: PanelModel type incositency const overrides = applyPanelTimeOverrides(panelModel, dashboardTimeRange); expect(overrides.timeRange.from.toISOString()).toBe(expectedFromDate.toISOString()); expect(overrides.timeRange.to.toISOString()).toBe(expectedToDate.toISOString()); - expect((overrides.timeRange.raw.from as moment.Moment).toISOString()).toEqual(expectedFromDate.toISOString()); - expect((overrides.timeRange.raw.to as moment.Moment).toISOString()).toEqual(expectedToDate.toISOString()); + expect((overrides.timeRange.raw.from as DateTime).toISOString()).toEqual(expectedFromDate.toISOString()); + expect((overrides.timeRange.raw.to as DateTime).toISOString()).toEqual(expectedToDate.toISOString()); }); it('should apply both relative time and time shift', () => { @@ -60,15 +60,15 @@ describe('applyPanelTimeOverrides', () => { timeShift: '2h', }; - const expectedFromDate = moment([2019, 1, 11, 10, 0, 0]).toDate(); - const expectedToDate = moment([2019, 1, 11, 12, 0, 0]).toDate(); + const expectedFromDate = dateTime([2019, 1, 11, 10, 0, 0]).toDate(); + const expectedToDate = dateTime([2019, 1, 11, 12, 0, 0]).toDate(); // @ts-ignore: PanelModel type incositency const overrides = applyPanelTimeOverrides(panelModel, dashboardTimeRange); expect(overrides.timeRange.from.toISOString()).toBe(expectedFromDate.toISOString()); expect(overrides.timeRange.to.toISOString()).toBe(expectedToDate.toISOString()); - expect((overrides.timeRange.raw.from as moment.Moment).toISOString()).toEqual(expectedFromDate.toISOString()); - expect((overrides.timeRange.raw.to as moment.Moment).toISOString()).toEqual(expectedToDate.toISOString()); + expect((overrides.timeRange.raw.from as DateTime).toISOString()).toEqual(expectedFromDate.toISOString()); + expect((overrides.timeRange.raw.to as DateTime).toISOString()).toEqual(expectedToDate.toISOString()); }); }); diff --git a/public/app/features/explore/GraphContainer.tsx b/public/app/features/explore/GraphContainer.tsx index ec3f330c616..fd0c0b680ec 100644 --- a/public/app/features/explore/GraphContainer.tsx +++ b/public/app/features/explore/GraphContainer.tsx @@ -1,7 +1,6 @@ import React, { PureComponent } from 'react'; import { hot } from 'react-hot-loader'; import { connect } from 'react-redux'; -import moment from 'moment'; import { TimeRange, TimeZone, AbsoluteTimeRange } from '@grafana/ui'; import { ExploreId, ExploreItemState } from 'app/types/explore'; @@ -11,6 +10,7 @@ import { toggleGraph, changeTime } from './state/actions'; import Graph from './Graph'; import Panel from './Panel'; import { getTimeZone } from '../profile/state/selectors'; +import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; interface GraphContainerProps { exploreId: ExploreId; @@ -34,8 +34,8 @@ export class GraphContainer extends PureComponent { onChangeTime = (absRange: AbsoluteTimeRange) => { const { exploreId, timeZone, changeTime } = this.props; const range = { - from: timeZone.isUtc ? moment.utc(absRange.from) : moment(absRange.from), - to: timeZone.isUtc ? moment.utc(absRange.to) : moment(absRange.to), + from: timeZone.isUtc ? toUtc(absRange.from) : dateTime(absRange.from), + to: timeZone.isUtc ? toUtc(absRange.to) : dateTime(absRange.to), }; changeTime(exploreId, range); diff --git a/public/app/features/explore/QueryEditor.tsx b/public/app/features/explore/QueryEditor.tsx index b271b0d9649..72613cbeb91 100644 --- a/public/app/features/explore/QueryEditor.tsx +++ b/public/app/features/explore/QueryEditor.tsx @@ -1,6 +1,5 @@ // Libraries import React, { PureComponent } from 'react'; -import moment from 'moment'; // Services import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; @@ -10,6 +9,7 @@ import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { Emitter } from 'app/core/utils/emitter'; import { DataQuery, TimeRange } from '@grafana/ui'; import 'app/features/plugins/plugin_loader'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; interface QueryEditorProps { datasource: any; @@ -67,8 +67,8 @@ export default class QueryEditor extends PureComponent { const timeSrv = getTimeSrv(); timeSrv.init({ time: { - from: moment(range.from), - to: moment(range.to), + from: dateTime(range.from), + to: dateTime(range.to), }, refresh: false, getTimezone: () => 'utc', diff --git a/public/app/features/explore/TimePicker.test.tsx b/public/app/features/explore/TimePicker.test.tsx index 49242675ab9..9cdf7a9b517 100644 --- a/public/app/features/explore/TimePicker.test.tsx +++ b/public/app/features/explore/TimePicker.test.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { shallow } from 'enzyme'; import sinon from 'sinon'; -import moment from 'moment'; import * as dateMath from '@grafana/ui/src/utils/datemath'; import * as rangeUtil from '@grafana/ui/src/utils/rangeutil'; import TimePicker from './TimePicker'; import { RawTimeRange, TimeRange, TIME_FORMAT } from '@grafana/ui'; +import { toUtc, isDateTime, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; const DEFAULT_RANGE = { from: 'now-6h', @@ -15,8 +15,8 @@ const DEFAULT_RANGE = { const fromRaw = (rawRange: RawTimeRange): TimeRange => { const raw = { - from: moment.isMoment(rawRange.from) ? moment(rawRange.from) : rawRange.from, - to: moment.isMoment(rawRange.to) ? moment(rawRange.to) : rawRange.to, + from: isDateTime(rawRange.from) ? dateTime(rawRange.from) : rawRange.from, + to: isDateTime(rawRange.to) ? dateTime(rawRange.to) : rawRange.to, }; return { @@ -73,19 +73,19 @@ describe('', () => { it('apply with absolute range and non-utc', () => { const range = { - from: moment.utc(1), - to: moment.utc(1000), + from: toUtc(1), + to: toUtc(1000), raw: { - from: moment.utc(1), - to: moment.utc(1000), + from: toUtc(1), + to: toUtc(1000), }, }; const localRange = { - from: moment(1), - to: moment(1000), + from: dateTime(1), + to: dateTime(1000), raw: { - from: moment(1), - to: moment(1000), + from: dateTime(1), + to: dateTime(1000), }, }; const expectedRangeString = rangeUtil.describeTimeRange(localRange); @@ -110,11 +110,11 @@ describe('', () => { it('apply with absolute range and utc', () => { const range = { - from: moment.utc(1), - to: moment.utc(1000), + from: toUtc(1), + to: toUtc(1000), raw: { - from: moment.utc(1), - to: moment.utc(1000), + from: toUtc(1), + to: toUtc(1000), }, }; const onChangeTime = sinon.spy(); @@ -137,11 +137,11 @@ describe('', () => { it('moves ranges backward by half the range on left arrow click when utc', () => { const rawRange = { - from: moment.utc(2000), - to: moment.utc(4000), + from: toUtc(2000), + to: toUtc(4000), raw: { - from: moment.utc(2000), - to: moment.utc(4000), + from: toUtc(2000), + to: toUtc(4000), }, }; const range = fromRaw(rawRange); @@ -159,19 +159,19 @@ describe('', () => { it('moves ranges backward by half the range on left arrow click when not utc', () => { const range = { - from: moment.utc(2000), - to: moment.utc(4000), + from: toUtc(2000), + to: toUtc(4000), raw: { - from: moment.utc(2000), - to: moment.utc(4000), + from: toUtc(2000), + to: toUtc(4000), }, }; const localRange = { - from: moment(2000), - to: moment(4000), + from: dateTime(2000), + to: dateTime(4000), raw: { - from: moment(2000), - to: moment(4000), + from: dateTime(2000), + to: dateTime(4000), }, }; @@ -188,11 +188,11 @@ describe('', () => { it('moves ranges forward by half the range on right arrow click when utc', () => { const range = { - from: moment.utc(1000), - to: moment.utc(3000), + from: toUtc(1000), + to: toUtc(3000), raw: { - from: moment.utc(1000), - to: moment.utc(3000), + from: toUtc(1000), + to: toUtc(3000), }, }; @@ -209,19 +209,19 @@ describe('', () => { it('moves ranges forward by half the range on right arrow click when not utc', () => { const range = { - from: moment.utc(1000), - to: moment.utc(3000), + from: toUtc(1000), + to: toUtc(3000), raw: { - from: moment.utc(1000), - to: moment.utc(3000), + from: toUtc(1000), + to: toUtc(3000), }, }; const localRange = { - from: moment(1000), - to: moment(3000), + from: dateTime(1000), + to: dateTime(3000), raw: { - from: moment(1000), - to: moment(3000), + from: dateTime(1000), + to: dateTime(3000), }, }; diff --git a/public/app/features/explore/TimePicker.tsx b/public/app/features/explore/TimePicker.tsx index 0e039d9a177..9a10edc0625 100644 --- a/public/app/features/explore/TimePicker.tsx +++ b/public/app/features/explore/TimePicker.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; -import moment from 'moment'; import * as rangeUtil from '@grafana/ui/src/utils/rangeutil'; import { Input, RawTimeRange, TimeRange, TIME_FORMAT } from '@grafana/ui'; +import { toUtc, isDateTime, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; interface TimePickerProps { isOpen?: boolean; @@ -28,14 +28,14 @@ const getRaw = (isUtc: boolean, range: any) => { to: range.raw.to, }; - if (moment.isMoment(rawRange.from)) { + if (isDateTime(rawRange.from)) { if (!isUtc) { rawRange.from = rawRange.from.local(); } rawRange.from = rawRange.from.format(TIME_FORMAT); } - if (moment.isMoment(rawRange.to)) { + if (isDateTime(rawRange.to)) { if (!isUtc) { rawRange.to = rawRange.to.local(); } @@ -99,8 +99,8 @@ export default class TimePicker extends PureComponent ({ getDatasourceSrv: () => ({ @@ -31,7 +31,7 @@ jest.mock('app/features/plugins/datasource_srv', () => ({ }), })); -const t = moment.utc(); +const t = toUtc(); const testRange = { from: t, to: t, diff --git a/public/app/features/explore/state/actions.ts b/public/app/features/explore/state/actions.ts index 0a430725155..4e8c25b15bd 100644 --- a/public/app/features/explore/state/actions.ts +++ b/public/app/features/explore/state/actions.ts @@ -1,6 +1,5 @@ // Libraries import _ from 'lodash'; -import moment from 'moment'; // Services & Utils import store from 'app/core/store'; @@ -87,6 +86,7 @@ import { import { ActionOf, ActionCreator } from 'app/core/redux/actionCreatorFactory'; import { LogsDedupStrategy } from 'app/core/logs_model'; import { getTimeZone } from 'app/features/profile/state/selectors'; +import { isDateTime } from '@grafana/ui/src/utils/moment_wrapper'; /** * Updates UI state and save it to the URL @@ -732,12 +732,12 @@ export function splitOpen(): ThunkResult { const toRawTimeRange = (range: TimeRange): RawTimeRange => { let from = range.raw.from; - if (moment.isMoment(from)) { + if (isDateTime(from)) { from = from.valueOf().toString(10); } let to = range.raw.to; - if (moment.isMoment(to)) { + if (isDateTime(to)) { to = to.valueOf().toString(10); } diff --git a/public/app/features/plugins/plugin_loader.ts b/public/app/features/plugins/plugin_loader.ts index c66803906f5..023757a9f82 100644 --- a/public/app/features/plugins/plugin_loader.ts +++ b/public/app/features/plugins/plugin_loader.ts @@ -1,3 +1,4 @@ +/* tslint:disable:import-blacklist */ import System from 'systemjs/dist/system.js'; import _ from 'lodash'; import * as sdk from 'app/plugins/sdk'; diff --git a/public/app/features/templating/specs/variable_srv.test.ts b/public/app/features/templating/specs/variable_srv.test.ts index 13281fecead..eac11d524c2 100644 --- a/public/app/features/templating/specs/variable_srv.test.ts +++ b/public/app/features/templating/specs/variable_srv.test.ts @@ -1,8 +1,8 @@ import '../all'; import { VariableSrv } from '../variable_srv'; import { DashboardModel } from '../../dashboard/state/DashboardModel'; -import moment from 'moment'; import $q from 'q'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('VariableSrv', function(this: any) { const ctx = { @@ -106,7 +106,7 @@ describe('VariableSrv', function(this: any) { }; const range = { - from: moment(new Date()) + from: dateTime(new Date()) .subtract(7, 'days') .toDate(), to: new Date(), @@ -514,7 +514,7 @@ describe('VariableSrv', function(this: any) { beforeEach(() => { const range = { - from: moment(new Date()) + from: dateTime(new Date()) .subtract(7, 'days') .toDate(), to: new Date(), diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index 1a3789a780f..b525f802fb0 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -1,9 +1,9 @@ import angular from 'angular'; import _ from 'lodash'; -import moment from 'moment'; import { ElasticResponse } from './elastic_response'; import { IndexPattern } from './index_pattern'; import { ElasticQueryBuilder } from './query_builder'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; export class ElasticDatasource { basicAuth: string; @@ -176,7 +176,7 @@ export class ElasticDatasource { const event = { annotation: annotation, - time: moment.utc(time).valueOf(), + time: toUtc(time).valueOf(), text: getFieldFromSource(source, textField), tags: getFieldFromSource(source, tagsField), }; diff --git a/public/app/plugins/datasource/elasticsearch/index_pattern.ts b/public/app/plugins/datasource/elasticsearch/index_pattern.ts index 1bf0514b32f..630777690b0 100644 --- a/public/app/plugins/datasource/elasticsearch/index_pattern.ts +++ b/public/app/plugins/datasource/elasticsearch/index_pattern.ts @@ -1,4 +1,4 @@ -import moment from 'moment'; +import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; const intervalMap = { Hourly: { startOf: 'hour', amount: 'hours' }, @@ -13,7 +13,7 @@ export class IndexPattern { getIndexForToday() { if (this.interval) { - return moment.utc().format(this.pattern); + return toUtc().format(this.pattern); } else { return this.pattern; } @@ -25,10 +25,10 @@ export class IndexPattern { } const intervalInfo = intervalMap[this.interval]; - const start = moment(from) + const start = dateTime(from) .utc() .startOf(intervalInfo.startOf); - const endEpoch = moment(to) + const endEpoch = dateTime(to) .utc() .startOf(intervalInfo.startOf) .valueOf(); diff --git a/public/app/plugins/datasource/elasticsearch/specs/datasource.test.ts b/public/app/plugins/datasource/elasticsearch/specs/datasource.test.ts index 01fa68959ca..6578129f391 100644 --- a/public/app/plugins/datasource/elasticsearch/specs/datasource.test.ts +++ b/public/app/plugins/datasource/elasticsearch/specs/datasource.test.ts @@ -1,8 +1,8 @@ import angular from 'angular'; import * as dateMath from '@grafana/ui/src/utils/datemath'; import _ from 'lodash'; -import moment from 'moment'; import { ElasticDatasource } from '../datasource'; +import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('ElasticDatasource', function(this: any) { const backendSrv = { @@ -66,7 +66,7 @@ describe('ElasticDatasource', function(this: any) { ctx.ds.testDatasource(); - const today = moment.utc().format('YYYY.MM.DD'); + const today = toUtc().format('YYYY.MM.DD'); expect(requestOptions.url).toBe('http://es.com/asd-' + today + '/_mapping'); }); }); @@ -105,8 +105,8 @@ describe('ElasticDatasource', function(this: any) { query = { range: { - from: moment.utc([2015, 4, 30, 10]), - to: moment.utc([2015, 5, 1, 10]), + from: toUtc([2015, 4, 30, 10]), + to: toUtc([2015, 5, 1, 10]), }, targets: [ { @@ -159,8 +159,8 @@ describe('ElasticDatasource', function(this: any) { ctx.ds.query({ range: { - from: moment([2015, 4, 30, 10]), - to: moment([2015, 5, 1, 10]), + from: dateTime([2015, 4, 30, 10]), + to: dateTime([2015, 5, 1, 10]), }, targets: [ { @@ -441,8 +441,8 @@ describe('ElasticDatasource', function(this: any) { ctx.ds.query({ range: { - from: moment([2015, 4, 30, 10]), - to: moment([2015, 5, 1, 10]), + from: dateTime([2015, 4, 30, 10]), + to: dateTime([2015, 5, 1, 10]), }, targets: [ { diff --git a/public/app/plugins/datasource/elasticsearch/specs/index_pattern.test.ts b/public/app/plugins/datasource/elasticsearch/specs/index_pattern.test.ts index c5cf4c9dee0..b930d88d77a 100644 --- a/public/app/plugins/datasource/elasticsearch/specs/index_pattern.test.ts +++ b/public/app/plugins/datasource/elasticsearch/specs/index_pattern.test.ts @@ -1,13 +1,13 @@ /// -import moment from 'moment'; import { IndexPattern } from '../index_pattern'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; describe('IndexPattern', () => { describe('when getting index for today', () => { test('should return correct index name', () => { const pattern = new IndexPattern('[asd-]YYYY.MM.DD', 'Daily'); - const expected = 'asd-' + moment.utc().format('YYYY.MM.DD'); + const expected = 'asd-' + toUtc().format('YYYY.MM.DD'); expect(pattern.getIndexForToday()).toBe(expected); }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts index c46ba9e2f92..df8c36175ae 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts @@ -1,7 +1,7 @@ import AzureMonitorDatasource from '../datasource'; import Q from 'q'; -import moment from 'moment'; import { TemplateSrv } from 'app/features/templating/template_srv'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; describe('AppInsightsDatasource', () => { const ctx: any = { @@ -110,8 +110,8 @@ describe('AppInsightsDatasource', () => { describe('When performing query', () => { const options = { range: { - from: moment.utc('2017-08-22T20:00:00Z'), - to: moment.utc('2017-08-22T23:59:00Z'), + from: toUtc('2017-08-22T20:00:00Z'), + to: toUtc('2017-08-22T23:59:00Z'), }, targets: [ { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_querystring_builder.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_querystring_builder.test.ts index a38ec95dc50..6ef7e051034 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_querystring_builder.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_querystring_builder.test.ts @@ -1,11 +1,11 @@ import AppInsightsQuerystringBuilder from './app_insights_querystring_builder'; -import moment from 'moment'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; describe('AppInsightsQuerystringBuilder', () => { let builder: AppInsightsQuerystringBuilder; beforeEach(() => { - builder = new AppInsightsQuerystringBuilder(moment.utc('2017-08-22 06:00'), moment.utc('2017-08-22 07:00'), '1h'); + builder = new AppInsightsQuerystringBuilder(toUtc('2017-08-22 06:00'), toUtc('2017-08-22 07:00'), '1h'); }); describe('with only from/to date range', () => { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/response_parser.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/response_parser.ts index 23f24e6f1fb..7a088c48e24 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/response_parser.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/response_parser.ts @@ -1,5 +1,5 @@ -import moment from 'moment'; import _ from 'lodash'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export default class ResponseParser { constructor(private results) {} @@ -173,8 +173,8 @@ export default class ResponseParser { return _.intersection(keys, ['sum', 'avg', 'min', 'max', 'count', 'unique'])[0]; } - static dateTimeToEpoch(dateTime) { - return moment(dateTime).valueOf(); + static dateTimeToEpoch(dateTimeValue) { + return dateTime(dateTimeValue).valueOf(); } static parseMetricNames(result) { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts index c6ff6dc5f75..c4ef792bc85 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts @@ -1,9 +1,9 @@ import AzureMonitorDatasource from '../datasource'; import FakeSchemaData from './__mocks__/schema'; import Q from 'q'; -import moment from 'moment'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { KustoSchema } from '../types'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; describe('AzureLogAnalyticsDatasource', () => { const ctx: any = { @@ -114,8 +114,8 @@ describe('AzureLogAnalyticsDatasource', () => { describe('When performing query', () => { const options = { range: { - from: moment.utc('2017-08-22T20:00:00Z'), - to: moment.utc('2017-08-22T23:59:00Z'), + from: toUtc('2017-08-22T20:00:00Z'), + to: toUtc('2017-08-22T23:59:00Z'), }, rangeRaw: { from: 'now-4h', @@ -376,8 +376,8 @@ describe('AzureLogAnalyticsDatasource', () => { workspace: 'abc1b44e-3e57-4410-b027-6cc0ae6dee67', }, range: { - from: moment.utc('2017-08-22T20:00:00Z'), - to: moment.utc('2017-08-22T23:59:00Z'), + from: toUtc('2017-08-22T20:00:00Z'), + to: toUtc('2017-08-22T23:59:00Z'), }, rangeRaw: { from: 'now-4h', diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts index 679ff5950a0..1860c4868be 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/response_parser.ts @@ -1,5 +1,5 @@ import _ from 'lodash'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; import { AzureLogsVariable, AzureLogsTableData, @@ -216,7 +216,7 @@ export default class ResponseParser { return dataTarget; } - static dateTimeToEpoch(dateTime) { - return moment(dateTime).valueOf(); + static dateTimeToEpoch(dateTimeValue) { + return dateTime(dateTimeValue).valueOf(); } } diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts index f36d72709d4..e4e718755b7 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts @@ -1,7 +1,7 @@ import AzureMonitorDatasource from '../datasource'; import Q from 'q'; -import moment from 'moment'; import { TemplateSrv } from 'app/features/templating/template_srv'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; describe('AzureMonitorDatasource', () => { const ctx: any = { @@ -79,8 +79,8 @@ describe('AzureMonitorDatasource', () => { describe('When performing query', () => { const options = { range: { - from: moment.utc('2017-08-22T20:00:00Z'), - to: moment.utc('2017-08-22T23:59:00Z'), + from: toUtc('2017-08-22T20:00:00Z'), + to: toUtc('2017-08-22T23:59:00Z'), }, targets: [ { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_filter_builder.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_filter_builder.test.ts index feaefbc5331..c848ed83c04 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_filter_builder.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_filter_builder.test.ts @@ -19,7 +19,7 @@ jest.mock('app/core/utils/kbn', () => { }); import AzureMonitorFilterBuilder from './azure_monitor_filter_builder'; -import moment from 'moment'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; describe('AzureMonitorFilterBuilder', () => { let builder: AzureMonitorFilterBuilder; @@ -30,8 +30,8 @@ describe('AzureMonitorFilterBuilder', () => { beforeEach(() => { builder = new AzureMonitorFilterBuilder( 'Percentage CPU', - moment.utc('2017-08-22 06:00'), - moment.utc('2017-08-22 07:00'), + toUtc('2017-08-22 06:00'), + toUtc('2017-08-22 07:00'), 'PT1H', '3m' ); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/response_parser.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/response_parser.ts index 878ac961939..84b9d78779b 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/response_parser.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/response_parser.ts @@ -1,6 +1,6 @@ -import moment from 'moment'; import _ from 'lodash'; import TimeGrainConverter from '../time_grain_converter'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export default class ResponseParser { constructor(private results) {} @@ -95,8 +95,8 @@ export default class ResponseParser { return dataPoints; } - static dateTimeToEpoch(dateTime) { - return moment(dateTime).valueOf(); + static dateTimeToEpoch(dateTimeValue) { + return dateTime(dateTimeValue).valueOf(); } static getKeyForAggregationField(dataObj): string { diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.test.ts index 24720edee34..fab268a3440 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.test.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.test.ts @@ -1,5 +1,5 @@ import LogAnalyticsQuerystringBuilder from './querystring_builder'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('LogAnalyticsDatasource', () => { let builder: LogAnalyticsQuerystringBuilder; @@ -10,8 +10,8 @@ describe('LogAnalyticsDatasource', () => { { interval: '5m', range: { - from: moment().subtract(24, 'hours'), - to: moment(), + from: dateTime().subtract(24, 'hours'), + to: dateTime(), }, rangeRaw: { from: 'now-24h', @@ -106,7 +106,7 @@ describe('LogAnalyticsDatasource', () => { describe('when using $__from and $__to is in the query and range is a specific interval', () => { beforeEach(() => { builder.rawQueryString = 'query=Tablename | where myTime >= $__from and myTime <= $__to'; - builder.options.range.to = moment().subtract(1, 'hour'); + builder.options.range.to = dateTime().subtract(1, 'hour'); builder.options.rangeRaw.to = 'now-1h'; }); diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.ts index b206d48756a..afb64da8f4c 100644 --- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.ts +++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/log_analytics/querystring_builder.ts @@ -1,4 +1,4 @@ -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export default class LogAnalyticsQuerystringBuilder { constructor(public rawQueryString, public options, public defaultTimeField) {} @@ -37,7 +37,7 @@ export default class LogAnalyticsQuerystringBuilder { getFrom(options) { const from = options.range.from; - return `datetime(${moment(from) + return `datetime(${dateTime(from) .startOf('minute') .toISOString()})`; } @@ -47,7 +47,7 @@ export default class LogAnalyticsQuerystringBuilder { return 'now()'; } else { const until = options.range.to; - return `datetime(${moment(until) + return `datetime(${dateTime(until) .startOf('minute') .toISOString()})`; } diff --git a/public/app/plugins/datasource/grafana/specs/datasource.test.ts b/public/app/plugins/datasource/grafana/specs/datasource.test.ts index 3c0205640e2..4c189ac4caa 100644 --- a/public/app/plugins/datasource/grafana/specs/datasource.test.ts +++ b/public/app/plugins/datasource/grafana/specs/datasource.test.ts @@ -1,6 +1,6 @@ import { GrafanaDatasource } from '../datasource'; import q from 'q'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('grafana data source', () => { describe('when executing an annotations query', () => { @@ -70,8 +70,8 @@ function setupAnnotationQueryOptions(annotation, dashboard?) { annotation: annotation, dashboard: dashboard, range: { - from: moment(1432288354), - to: moment(1432288401), + from: dateTime(1432288354), + to: dateTime(1432288401), }, rangeRaw: { from: 'now-24h', to: 'now' }, }; diff --git a/public/app/plugins/datasource/graphite/specs/datasource.test.ts b/public/app/plugins/datasource/graphite/specs/datasource.test.ts index cd60a059123..de98f55172b 100644 --- a/public/app/plugins/datasource/graphite/specs/datasource.test.ts +++ b/public/app/plugins/datasource/graphite/specs/datasource.test.ts @@ -1,8 +1,8 @@ import { GraphiteDatasource } from '../datasource'; -import moment from 'moment'; import _ from 'lodash'; import $q from 'q'; import { TemplateSrvStub } from 'test/specs/helpers'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('graphiteDatasource', () => { const ctx: any = { @@ -86,8 +86,8 @@ describe('graphiteDatasource', () => { tags: 'tag1', }, range: { - from: moment(1432288354), - to: moment(1432288401), + from: dateTime(1432288354), + to: dateTime(1432288401), }, rangeRaw: { from: 'now-24h', to: 'now' }, }; diff --git a/public/app/plugins/datasource/loki/language_provider.ts b/public/app/plugins/datasource/loki/language_provider.ts index c137deace1c..64bf876f2c7 100644 --- a/public/app/plugins/datasource/loki/language_provider.ts +++ b/public/app/plugins/datasource/loki/language_provider.ts @@ -1,6 +1,5 @@ // Libraries import _ from 'lodash'; -import moment from 'moment'; // Services & Utils import { parseSelector, labelRegexp, selectorRegexp } from 'app/plugins/datasource/prometheus/language_utils'; @@ -16,6 +15,7 @@ import { HistoryItem, } from 'app/types/explore'; import { LokiQuery } from './types'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; const DEFAULT_KEYS = ['job', 'namespace']; const EMPTY_SELECTOR = '{}'; @@ -34,7 +34,7 @@ export function addHistoryMetadata(item: CompletionItem, history: LokiHistoryIte const recent = historyForItem[0]; let hint = `Queried ${count} times in the last 24h.`; if (recent) { - const lastQueried = moment(recent.ts).fromNow(); + const lastQueried = dateTime(recent.ts).fromNow(); hint = `${hint} Last queried ${lastQueried}.`; } return { diff --git a/public/app/plugins/datasource/mssql/specs/datasource.test.ts b/public/app/plugins/datasource/mssql/specs/datasource.test.ts index 49b13387369..357d4e41ccf 100644 --- a/public/app/plugins/datasource/mssql/specs/datasource.test.ts +++ b/public/app/plugins/datasource/mssql/specs/datasource.test.ts @@ -1,8 +1,8 @@ -import moment from 'moment'; import { MssqlDatasource } from '../datasource'; import { TemplateSrvStub, TimeSrvStub } from 'test/specs/helpers'; import { CustomVariable } from 'app/features/templating/custom_variable'; import q from 'q'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('MSSQLDatasource', () => { const ctx: any = { @@ -29,8 +29,8 @@ describe('MSSQLDatasource', () => { rawQuery: 'select time, text, tags from table;', }, range: { - from: moment(1432288354), - to: moment(1432288401), + from: dateTime(1432288354), + to: dateTime(1432288401), }, }; @@ -209,8 +209,8 @@ describe('MSSQLDatasource', () => { }, }; const time = { - from: moment(1521545610656), - to: moment(1521546251185), + from: dateTime(1521545610656), + to: dateTime(1521546251185), }; beforeEach(() => { diff --git a/public/app/plugins/datasource/mysql/specs/datasource.test.ts b/public/app/plugins/datasource/mysql/specs/datasource.test.ts index f3fbcd93333..9b3249c87e1 100644 --- a/public/app/plugins/datasource/mysql/specs/datasource.test.ts +++ b/public/app/plugins/datasource/mysql/specs/datasource.test.ts @@ -1,6 +1,6 @@ -import moment from 'moment'; import { MysqlDatasource } from '../datasource'; import { CustomVariable } from 'app/features/templating/custom_variable'; +import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('MySQLDatasource', () => { const instanceSettings = { name: 'mysql' }; @@ -10,8 +10,8 @@ describe('MySQLDatasource', () => { }; const raw = { - from: moment.utc('2018-04-25 10:00'), - to: moment.utc('2018-04-25 11:00'), + from: toUtc('2018-04-25 10:00'), + to: toUtc('2018-04-25 11:00'), }; const ctx = { backendSrv, @@ -39,8 +39,8 @@ describe('MySQLDatasource', () => { rawQuery: 'select time_sec, text, tags from table;', }, range: { - from: moment(1432288354), - to: moment(1432288401), + from: dateTime(1432288354), + to: dateTime(1432288401), }, }; diff --git a/public/app/plugins/datasource/postgres/specs/datasource.test.ts b/public/app/plugins/datasource/postgres/specs/datasource.test.ts index 49541028caf..7c55b876823 100644 --- a/public/app/plugins/datasource/postgres/specs/datasource.test.ts +++ b/public/app/plugins/datasource/postgres/specs/datasource.test.ts @@ -1,6 +1,6 @@ -import moment from 'moment'; import { PostgresDatasource } from '../datasource'; import { CustomVariable } from 'app/features/templating/custom_variable'; +import { toUtc, dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('PostgreSQLDatasource', () => { const instanceSettings = { name: 'postgresql' }; @@ -10,8 +10,8 @@ describe('PostgreSQLDatasource', () => { replace: jest.fn(text => text), }; const raw = { - from: moment.utc('2018-04-25 10:00'), - to: moment.utc('2018-04-25 11:00'), + from: toUtc('2018-04-25 10:00'), + to: toUtc('2018-04-25 11:00'), }; const ctx = { backendSrv, @@ -39,8 +39,8 @@ describe('PostgreSQLDatasource', () => { rawQuery: 'select time, title, text, tags from table;', }, range: { - from: moment(1432288354), - to: moment(1432288401), + from: dateTime(1432288354), + to: dateTime(1432288401), }, }; diff --git a/public/app/plugins/datasource/prometheus/language_provider.ts b/public/app/plugins/datasource/prometheus/language_provider.ts index 9acc7a33f21..b281fe03336 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.ts @@ -1,5 +1,4 @@ import _ from 'lodash'; -import moment from 'moment'; import { CompletionItem, @@ -11,6 +10,7 @@ import { import { parseSelector, processLabels, processHistogramLabels } from './language_utils'; import PromqlSyntax, { FUNCTIONS, RATE_RANGES } from './promql'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; const DEFAULT_KEYS = ['job', 'instance']; const EMPTY_SELECTOR = '{}'; @@ -31,7 +31,7 @@ export function addHistoryMetadata(item: CompletionItem, history: any[]): Comple const recent = historyForItem[0]; let hint = `Queried ${count} times in the last 24h.`; if (recent) { - const lastQueried = moment(recent.ts).fromNow(); + const lastQueried = dateTime(recent.ts).fromNow(); hint = `${hint} Last queried ${lastQueried}.`; } return { diff --git a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts index 05808464115..1c106482945 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts @@ -1,5 +1,4 @@ import _ from 'lodash'; -import moment from 'moment'; import q from 'q'; import { alignRange, @@ -8,6 +7,7 @@ import { prometheusRegularEscape, prometheusSpecialRegexEscape, } from '../datasource'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; jest.mock('../metric_find_query'); @@ -33,8 +33,8 @@ describe('PrometheusDatasource', () => { ctx.timeSrvMock = { timeRange: () => { return { - from: moment(1531468681), - to: moment(1531489712), + from: dateTime(1531468681), + to: dateTime(1531489712), }; }, }; @@ -135,7 +135,7 @@ describe('PrometheusDatasource', () => { describe('When converting prometheus histogram to heatmap format', () => { beforeEach(() => { ctx.query = { - range: { from: moment(1443454528000), to: moment(1443454528000) }, + range: { from: dateTime(1443454528000), to: dateTime(1443454528000) }, targets: [{ expr: 'test{job="testjob"}', format: 'heatmap', legendFormat: '{{le}}' }], interval: '1s', }; @@ -310,8 +310,8 @@ describe('PrometheusDatasource', () => { ctx.templateSrvMock.replace = jest.fn(); ctx.timeSrvMock.timeRange = () => { return { - from: moment(1531468681), - to: moment(1531489712), + from: dateTime(1531468681), + to: dateTime(1531489712), }; }; ctx.ds = new PrometheusDatasource(instanceSettings, q, ctx.backendSrvMock, ctx.templateSrvMock, ctx.timeSrvMock); @@ -344,7 +344,7 @@ const SECOND = 1000; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; -const time = ({ hours = 0, seconds = 0, minutes = 0 }) => moment(hours * HOUR + minutes * MINUTE + seconds * SECOND); +const time = ({ hours = 0, seconds = 0, minutes = 0 }) => dateTime(hours * HOUR + minutes * MINUTE + seconds * SECOND); const ctx = {} as any; const instanceSettings = { diff --git a/public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts b/public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts index 2ca7c978762..3098d44aba2 100644 --- a/public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts @@ -1,7 +1,7 @@ -import moment from 'moment'; import { PrometheusDatasource } from '../datasource'; import PrometheusMetricFindQuery from '../metric_find_query'; import q from 'q'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; describe('PrometheusMetricFindQuery', () => { const instanceSettings = { @@ -12,8 +12,8 @@ describe('PrometheusMetricFindQuery', () => { jsonData: { httpMethod: 'GET' }, }; const raw = { - from: moment.utc('2018-04-25 10:00'), - to: moment.utc('2018-04-25 11:00'), + from: toUtc('2018-04-25 10:00'), + to: toUtc('2018-04-25 11:00'), }; const ctx: any = { backendSrvMock: { diff --git a/public/app/plugins/datasource/stackdriver/specs/datasource.test.ts b/public/app/plugins/datasource/stackdriver/specs/datasource.test.ts index 032f10d8ca5..b9c8ac71064 100644 --- a/public/app/plugins/datasource/stackdriver/specs/datasource.test.ts +++ b/public/app/plugins/datasource/stackdriver/specs/datasource.test.ts @@ -1,8 +1,8 @@ import StackdriverDataSource from '../datasource'; import { metricDescriptors } from './testData'; -import moment from 'moment'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { CustomVariable } from 'app/features/templating/all'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; describe('StackdriverDataSource', () => { const instanceSettings = { @@ -73,8 +73,8 @@ describe('StackdriverDataSource', () => { describe('When performing query', () => { const options = { range: { - from: moment.utc('2017-08-22T20:00:00Z'), - to: moment.utc('2017-08-22T23:59:00Z'), + from: toUtc('2017-08-22T20:00:00Z'), + to: toUtc('2017-08-22T23:59:00Z'), }, rangeRaw: { from: 'now-4h', diff --git a/public/app/plugins/datasource/testdata/query_ctrl.ts b/public/app/plugins/datasource/testdata/query_ctrl.ts index c0667a33000..79242ba0c50 100644 --- a/public/app/plugins/datasource/testdata/query_ctrl.ts +++ b/public/app/plugins/datasource/testdata/query_ctrl.ts @@ -1,9 +1,9 @@ import _ from 'lodash'; import { QueryCtrl } from 'app/plugins/sdk'; -import moment from 'moment'; import { defaultQuery } from './StreamHandler'; import { getBackendSrv } from 'app/core/services/backend_srv'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export class TestDataQueryCtrl extends QueryCtrl { static templateUrl = 'partials/query.editor.html'; @@ -20,14 +20,14 @@ export class TestDataQueryCtrl extends QueryCtrl { this.target.scenarioId = this.target.scenarioId || 'random_walk'; this.scenarioList = []; - this.newPointTime = moment(); + this.newPointTime = dateTime(); this.selectedPoint = { text: 'Select point', value: null }; } getPoints() { return _.map(this.target.points, (point, index) => { return { - text: moment(point[1]).format('MMMM Do YYYY, H:mm:ss') + ' : ' + point[0], + text: dateTime(point[1]).format('MMMM Do YYYY, H:mm:ss') + ' : ' + point[0], value: index, }; }); diff --git a/public/app/plugins/panel/alertlist/module.ts b/public/app/plugins/panel/alertlist/module.ts index 56cfe47ca6f..d602c6d77a0 100644 --- a/public/app/plugins/panel/alertlist/module.ts +++ b/public/app/plugins/panel/alertlist/module.ts @@ -1,9 +1,9 @@ import _ from 'lodash'; -import moment from 'moment'; import alertDef from '../../../features/alerting/state/alertDef'; import { PanelCtrl } from 'app/plugins/sdk'; import * as dateMath from '@grafana/ui/src/utils/datemath'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; class AlertListPanel extends PanelCtrl { static templateUrl = 'module.html'; @@ -157,7 +157,7 @@ class AlertListPanel extends PanelCtrl { this.currentAlerts = this.sortResult( _.map(res, al => { al.stateModel = alertDef.getStateDisplayModel(al.state); - al.newStateDateAgo = moment(al.newStateDate) + al.newStateDateAgo = dateTime(al.newStateDate) .locale('en') .fromNow(true); return al; diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index abed226f9d6..dad49788eb0 100644 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -10,7 +10,6 @@ import './jquery.flot.events'; import $ from 'jquery'; import _ from 'lodash'; -import moment from 'moment'; import { tickStep } from 'app/core/utils/ticks'; import { appEvents, coreModule, updateLegendValues } from 'app/core/core'; import GraphTooltip from './graph_tooltip'; @@ -27,6 +26,7 @@ import { Legend, GraphLegendProps } from './Legend/Legend'; import { GraphCtrl } from './module'; import { getValueFormat } from '@grafana/ui'; import { provideTheme } from 'app/core/utils/ConfigProvider'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; const LegendWithThemeProvider = provideTheme(Legend); @@ -164,8 +164,8 @@ class GraphElement { } else { this.scope.$apply(() => { this.timeSrv.setTime({ - from: moment.utc(ranges.xaxis.from), - to: moment.utc(ranges.xaxis.to), + from: toUtc(ranges.xaxis.from), + to: toUtc(ranges.xaxis.to), }); }); } diff --git a/public/app/plugins/panel/graph/specs/graph.test.ts b/public/app/plugins/panel/graph/specs/graph.test.ts index ff81a8ae6eb..aa022c68607 100644 --- a/public/app/plugins/panel/graph/specs/graph.test.ts +++ b/public/app/plugins/panel/graph/specs/graph.test.ts @@ -24,17 +24,17 @@ import { PanelCtrl } from 'app/features/panel/panel_ctrl'; import config from 'app/core/config'; import TimeSeries from 'app/core/time_series2'; -import moment from 'moment'; import $ from 'jquery'; import { graphDirective } from '../graph'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; const ctx = {} as any; let ctrl; const scope = { ctrl: {}, range: { - from: moment([2015, 1, 1]), - to: moment([2015, 11, 20]), + from: dateTime([2015, 1, 1]), + to: dateTime([2015, 11, 20]), }, $on: () => {}, }; @@ -85,8 +85,8 @@ describe('grafanaGraph', () => { getTimezone: () => 'browser', }, range: { - from: moment([2015, 1, 1, 10]), - to: moment([2015, 1, 1, 22]), + from: dateTime([2015, 1, 1, 10]), + to: dateTime([2015, 1, 1, 22]), }, } as any; @@ -443,8 +443,8 @@ describe('grafanaGraph', () => { describe('and the range is less than 24 hours', () => { beforeEach(() => { setupCtx(() => { - ctrl.range.from = moment([2015, 1, 1, 10]); - ctrl.range.to = moment([2015, 1, 1, 22]); + ctrl.range.from = dateTime([2015, 1, 1, 10]); + ctrl.range.to = dateTime([2015, 1, 1, 22]); }); }); @@ -457,8 +457,8 @@ describe('grafanaGraph', () => { describe('and the range is less than one year', () => { beforeEach(() => { setupCtx(() => { - ctrl.range.from = moment([2015, 1, 1]); - ctrl.range.to = moment([2015, 11, 20]); + ctrl.range.from = dateTime([2015, 1, 1]); + ctrl.range.to = dateTime([2015, 11, 20]); }); }); diff --git a/public/app/plugins/panel/graph/specs/graph_ctrl.test.ts b/public/app/plugins/panel/graph/specs/graph_ctrl.test.ts index 826b71f429e..114d32eba4a 100644 --- a/public/app/plugins/panel/graph/specs/graph_ctrl.test.ts +++ b/public/app/plugins/panel/graph/specs/graph_ctrl.test.ts @@ -1,5 +1,5 @@ -import moment from 'moment'; import { GraphCtrl } from '../module'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; jest.mock('../graph', () => ({})); @@ -50,7 +50,7 @@ describe('GraphCtrl', () => { }, ]; - ctx.ctrl.range = { from: moment().valueOf(), to: moment().valueOf() }; + ctx.ctrl.range = { from: dateTime().valueOf(), to: dateTime().valueOf() }; ctx.ctrl.onDataReceived(data); }); @@ -62,10 +62,10 @@ describe('GraphCtrl', () => { describe('when time series are inside range', () => { beforeEach(() => { const range = { - from: moment() + from: dateTime() .subtract(1, 'days') .valueOf(), - to: moment().valueOf(), + to: dateTime().valueOf(), }; const data = [ diff --git a/public/app/plugins/panel/graph/specs/time_region_manager.test.ts b/public/app/plugins/panel/graph/specs/time_region_manager.test.ts index 266838ce9b0..97d63bbb75a 100644 --- a/public/app/plugins/panel/graph/specs/time_region_manager.test.ts +++ b/public/app/plugins/panel/graph/specs/time_region_manager.test.ts @@ -1,5 +1,5 @@ import { TimeRegionManager, colorModes } from '../time_region_manager'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('TimeRegionManager', () => { function plotOptionsScenario(desc, func) { @@ -32,9 +32,11 @@ describe('TimeRegionManager', () => { `Time range: from=${ctx.panelCtrl.range.from.format()}, to=${ctx.panelCtrl.range.to.format()}`, ctx.panelCtrl.range.from._isUTC ); - ctx.options.grid.markings.forEach((m, i) => { + ctx.options.grid.markings.forEach((m: any, i: number) => { console.log( - `Marking (${i}): from=${moment(m.xaxis.from).format()}, to=${moment(m.xaxis.to).format()}, color=${m.color}` + `Marking (${i}): from=${dateTime(m.xaxis.from).format()}, to=${dateTime(m.xaxis.to).format()}, color=${ + m.color + }` ); }); }; @@ -48,16 +50,16 @@ describe('TimeRegionManager', () => { const regions = [ { fromDayOfWeek: 1, toDayOfWeek: 1, fill: true, line: true, lineColor: '#ffffff', colorMode: 'custom' }, ]; - const from = moment('2018-01-01T00:00:00+01:00'); - const to = moment('2018-01-01T23:59:00+01:00'); + const from = dateTime('2018-01-01T00:00:00+01:00'); + const to = dateTime('2018-01-01T23:59:00+01:00'); expect(() => ctx.setup(regions, from, to)).not.toThrow(); }); plotOptionsScenario('should not throw an error when lineColor is undefined', ctx => { const regions = [ { fromDayOfWeek: 1, toDayOfWeek: 1, fill: true, fillColor: '#ffffff', line: true, colorMode: 'custom' }, ]; - const from = moment('2018-01-01T00:00:00+01:00'); - const to = moment('2018-01-01T23:59:00+01:00'); + const from = dateTime('2018-01-01T00:00:00+01:00'); + const to = dateTime('2018-01-01T23:59:00+01:00'); expect(() => ctx.setup(regions, from, to)).not.toThrow(); }); }); @@ -65,8 +67,8 @@ describe('TimeRegionManager', () => { describe('When creating plot markings using local time', () => { plotOptionsScenario('for day of week region', ctx => { const regions = [{ fromDayOfWeek: 1, toDayOfWeek: 1, fill: true, line: true, colorMode: 'red' }]; - const from = moment('2018-01-01T00:00:00+01:00'); - const to = moment('2018-01-01T23:59:00+01:00'); + const from = dateTime('2018-01-01T00:00:00+01:00'); + const to = dateTime('2018-01-01T23:59:00+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -75,30 +77,30 @@ describe('TimeRegionManager', () => { it('should add fill', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-01-01T01:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-01-02T00:59:59+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-01-01T01:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-01-02T00:59:59+01:00').format()); expect(markings[0].color).toBe(colorModes.red.color.fill); }); it('should add line before', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-01-01T01:00:00+01:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-01-01T01:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-01-01T01:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-01-01T01:00:00+01:00').format()); expect(markings[1].color).toBe(colorModes.red.color.line); }); it('should add line after', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-01-02T00:59:59+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-01-02T00:59:59+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-01-02T00:59:59+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-01-02T00:59:59+01:00').format()); expect(markings[2].color).toBe(colorModes.red.color.line); }); }); plotOptionsScenario('for time from region', ctx => { const regions = [{ from: '05:00', fill: true, colorMode: 'red' }]; - const from = moment('2018-01-01T00:00+01:00'); - const to = moment('2018-01-03T23:59+01:00'); + const from = dateTime('2018-01-01T00:00+01:00'); + const to = dateTime('2018-01-03T23:59+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -108,24 +110,24 @@ describe('TimeRegionManager', () => { it('should add one fill at 05:00 each day', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-01-01T06:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-01-01T06:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-01-01T06:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-01-01T06:00:00+01:00').format()); expect(markings[0].color).toBe(colorModes.red.color.fill); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-01-02T06:00:00+01:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-01-02T06:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-01-02T06:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-01-02T06:00:00+01:00').format()); expect(markings[1].color).toBe(colorModes.red.color.fill); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-01-03T06:00:00+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-01-03T06:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-01-03T06:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-01-03T06:00:00+01:00').format()); expect(markings[2].color).toBe(colorModes.red.color.fill); }); }); plotOptionsScenario('for time to region', ctx => { const regions = [{ to: '05:00', fill: true, colorMode: 'red' }]; - const from = moment('2018-02-01T00:00+01:00'); - const to = moment('2018-02-03T23:59+01:00'); + const from = dateTime('2018-02-01T00:00+01:00'); + const to = dateTime('2018-02-03T23:59+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -135,24 +137,24 @@ describe('TimeRegionManager', () => { it('should add one fill at 05:00 each day', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-02-01T06:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-02-01T06:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-02-01T06:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-02-01T06:00:00+01:00').format()); expect(markings[0].color).toBe(colorModes.red.color.fill); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-02-02T06:00:00+01:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-02-02T06:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-02-02T06:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-02-02T06:00:00+01:00').format()); expect(markings[1].color).toBe(colorModes.red.color.fill); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-02-03T06:00:00+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-02-03T06:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-02-03T06:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-02-03T06:00:00+01:00').format()); expect(markings[2].color).toBe(colorModes.red.color.fill); }); }); plotOptionsScenario('for time from/to region', ctx => { const regions = [{ from: '00:00', to: '05:00', fill: true, colorMode: 'red' }]; - const from = moment('2018-12-01T00:00+01:00'); - const to = moment('2018-12-03T23:59+01:00'); + const from = dateTime('2018-12-01T00:00+01:00'); + const to = dateTime('2018-12-03T23:59+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -162,24 +164,24 @@ describe('TimeRegionManager', () => { it('should add one fill between 00:00 and 05:00 each day', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-12-01T01:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-12-01T06:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-12-01T01:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-12-01T06:00:00+01:00').format()); expect(markings[0].color).toBe(colorModes.red.color.fill); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-12-02T01:00:00+01:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-12-02T06:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-12-02T01:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-12-02T06:00:00+01:00').format()); expect(markings[1].color).toBe(colorModes.red.color.fill); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-12-03T01:00:00+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-12-03T06:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-12-03T01:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-12-03T06:00:00+01:00').format()); expect(markings[2].color).toBe(colorModes.red.color.fill); }); }); plotOptionsScenario('for time from/to region crossing midnight', ctx => { const regions = [{ from: '22:00', to: '00:30', fill: true, colorMode: 'red' }]; - const from = moment('2018-12-01T12:00+01:00'); - const to = moment('2018-12-04T08:00+01:00'); + const from = dateTime('2018-12-01T12:00+01:00'); + const to = dateTime('2018-12-04T08:00+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -189,24 +191,24 @@ describe('TimeRegionManager', () => { it('should add one fill between 22:00 and 00:30 each day', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-12-01T23:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-12-02T01:30:00+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-12-01T23:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-12-02T01:30:00+01:00').format()); expect(markings[0].color).toBe(colorModes.red.color.fill); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-12-02T23:00:00+01:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-12-03T01:30:00+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-12-02T23:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-12-03T01:30:00+01:00').format()); expect(markings[1].color).toBe(colorModes.red.color.fill); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-12-03T23:00:00+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-12-04T01:30:00+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-12-03T23:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-12-04T01:30:00+01:00').format()); expect(markings[2].color).toBe(colorModes.red.color.fill); }); }); plotOptionsScenario('for day of week from/to region', ctx => { const regions = [{ fromDayOfWeek: 7, toDayOfWeek: 7, fill: true, colorMode: 'red' }]; - const from = moment('2018-01-01T18:45:05+01:00'); - const to = moment('2018-01-22T08:27:00+01:00'); + const from = dateTime('2018-01-01T18:45:05+01:00'); + const to = dateTime('2018-01-22T08:27:00+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -216,24 +218,24 @@ describe('TimeRegionManager', () => { it('should add one fill at each sunday', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-01-07T01:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-01-08T00:59:59+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-01-07T01:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-01-08T00:59:59+01:00').format()); expect(markings[0].color).toBe(colorModes.red.color.fill); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-01-14T01:00:00+01:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-01-15T00:59:59+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-01-14T01:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-01-15T00:59:59+01:00').format()); expect(markings[1].color).toBe(colorModes.red.color.fill); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-01-21T01:00:00+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-01-22T00:59:59+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-01-21T01:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-01-22T00:59:59+01:00').format()); expect(markings[2].color).toBe(colorModes.red.color.fill); }); }); plotOptionsScenario('for day of week from region', ctx => { const regions = [{ fromDayOfWeek: 7, fill: true, colorMode: 'red' }]; - const from = moment('2018-01-01T18:45:05+01:00'); - const to = moment('2018-01-22T08:27:00+01:00'); + const from = dateTime('2018-01-01T18:45:05+01:00'); + const to = dateTime('2018-01-22T08:27:00+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -243,24 +245,24 @@ describe('TimeRegionManager', () => { it('should add one fill at each sunday', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-01-07T01:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-01-08T00:59:59+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-01-07T01:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-01-08T00:59:59+01:00').format()); expect(markings[0].color).toBe(colorModes.red.color.fill); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-01-14T01:00:00+01:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-01-15T00:59:59+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-01-14T01:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-01-15T00:59:59+01:00').format()); expect(markings[1].color).toBe(colorModes.red.color.fill); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-01-21T01:00:00+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-01-22T00:59:59+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-01-21T01:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-01-22T00:59:59+01:00').format()); expect(markings[2].color).toBe(colorModes.red.color.fill); }); }); plotOptionsScenario('for day of week to region', ctx => { const regions = [{ toDayOfWeek: 7, fill: true, colorMode: 'red' }]; - const from = moment('2018-01-01T18:45:05+01:00'); - const to = moment('2018-01-22T08:27:00+01:00'); + const from = dateTime('2018-01-01T18:45:05+01:00'); + const to = dateTime('2018-01-22T08:27:00+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -270,24 +272,24 @@ describe('TimeRegionManager', () => { it('should add one fill at each sunday', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-01-07T01:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-01-08T00:59:59+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-01-07T01:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-01-08T00:59:59+01:00').format()); expect(markings[0].color).toBe(colorModes.red.color.fill); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-01-14T01:00:00+01:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-01-15T00:59:59+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-01-14T01:00:00+01:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-01-15T00:59:59+01:00').format()); expect(markings[1].color).toBe(colorModes.red.color.fill); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-01-21T01:00:00+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-01-22T00:59:59+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-01-21T01:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-01-22T00:59:59+01:00').format()); expect(markings[2].color).toBe(colorModes.red.color.fill); }); }); plotOptionsScenario('for day of week from/to time region', ctx => { const regions = [{ fromDayOfWeek: 7, from: '23:00', toDayOfWeek: 1, to: '01:40', fill: true, colorMode: 'red' }]; - const from = moment('2018-12-07T12:51:19+01:00'); - const to = moment('2018-12-10T13:51:29+01:00'); + const from = dateTime('2018-12-07T12:51:19+01:00'); + const to = dateTime('2018-12-10T13:51:29+01:00'); ctx.setup(regions, from, to); it('should add 1 marking', () => { @@ -297,15 +299,15 @@ describe('TimeRegionManager', () => { it('should add one fill between sunday 23:00 and monday 01:40', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-12-10T00:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-12-10T02:40:00+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-12-10T00:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-12-10T02:40:00+01:00').format()); }); }); plotOptionsScenario('for day of week from/to time region', ctx => { const regions = [{ fromDayOfWeek: 6, from: '03:00', toDayOfWeek: 7, to: '02:00', fill: true, colorMode: 'red' }]; - const from = moment('2018-12-07T12:51:19+01:00'); - const to = moment('2018-12-10T13:51:29+01:00'); + const from = dateTime('2018-12-07T12:51:19+01:00'); + const to = dateTime('2018-12-10T13:51:29+01:00'); ctx.setup(regions, from, to); it('should add 1 marking', () => { @@ -315,15 +317,15 @@ describe('TimeRegionManager', () => { it('should add one fill between saturday 03:00 and sunday 02:00', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-12-08T04:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-12-09T03:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-12-08T04:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-12-09T03:00:00+01:00').format()); }); }); plotOptionsScenario('for day of week from/to time region with daylight saving time', ctx => { const regions = [{ fromDayOfWeek: 7, from: '20:00', toDayOfWeek: 7, to: '23:00', fill: true, colorMode: 'red' }]; - const from = moment('2018-03-17T06:00:00+01:00'); - const to = moment('2018-04-03T06:00:00+02:00'); + const from = dateTime('2018-03-17T06:00:00+01:00'); + const to = dateTime('2018-04-03T06:00:00+02:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -333,21 +335,21 @@ describe('TimeRegionManager', () => { it('should add one fill at each sunday between 20:00 and 23:00', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-03-18T21:00:00+01:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-03-19T00:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-03-18T21:00:00+01:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-03-19T00:00:00+01:00').format()); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-03-25T22:00:00+02:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-03-26T01:00:00+02:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-03-25T22:00:00+02:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-03-26T01:00:00+02:00').format()); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-04-01T22:00:00+02:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-04-02T01:00:00+02:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-04-01T22:00:00+02:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-04-02T01:00:00+02:00').format()); }); }); plotOptionsScenario('for each day of week with winter time', ctx => { const regions = [{ fromDayOfWeek: 7, toDayOfWeek: 7, fill: true, colorMode: 'red' }]; - const from = moment('2018-10-20T14:50:11+02:00'); - const to = moment('2018-11-07T12:56:23+01:00'); + const from = dateTime('2018-10-20T14:50:11+02:00'); + const to = dateTime('2018-11-07T12:56:23+01:00'); ctx.setup(regions, from, to); it('should add 3 markings', () => { @@ -357,14 +359,14 @@ describe('TimeRegionManager', () => { it('should add one fill at each sunday', () => { const markings = ctx.options.grid.markings; - expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-10-21T02:00:00+02:00').format()); - expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-10-22T01:59:59+02:00').format()); + expect(dateTime(markings[0].xaxis.from).format()).toBe(dateTime('2018-10-21T02:00:00+02:00').format()); + expect(dateTime(markings[0].xaxis.to).format()).toBe(dateTime('2018-10-22T01:59:59+02:00').format()); - expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-10-28T02:00:00+02:00').format()); - expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-10-29T00:59:59+01:00').format()); + expect(dateTime(markings[1].xaxis.from).format()).toBe(dateTime('2018-10-28T02:00:00+02:00').format()); + expect(dateTime(markings[1].xaxis.to).format()).toBe(dateTime('2018-10-29T00:59:59+01:00').format()); - expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-11-04T01:00:00+01:00').format()); - expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-11-05T00:59:59+01:00').format()); + expect(dateTime(markings[2].xaxis.from).format()).toBe(dateTime('2018-11-04T01:00:00+01:00').format()); + expect(dateTime(markings[2].xaxis.to).format()).toBe(dateTime('2018-11-05T00:59:59+01:00').format()); }); }); }); diff --git a/public/app/plugins/panel/graph/time_region_manager.ts b/public/app/plugins/panel/graph/time_region_manager.ts index a04096bc371..1aaeb09b44a 100644 --- a/public/app/plugins/panel/graph/time_region_manager.ts +++ b/public/app/plugins/panel/graph/time_region_manager.ts @@ -1,7 +1,7 @@ import 'vendor/flot/jquery.flot'; import _ from 'lodash'; -import moment from 'moment'; import { GrafanaThemeType, getColorFromHexRgbOrName } from '@grafana/ui'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; type TimeRegionColorDefinition = { fill: string; @@ -83,7 +83,10 @@ export class TimeRegionManager { return; } - const tRange = { from: moment(this.panelCtrl.range.from).utc(), to: moment(this.panelCtrl.range.to).utc() }; + const tRange = { + from: dateTime(this.panelCtrl.range.from).utc(), + to: dateTime(this.panelCtrl.range.to).utc(), + }; let i, hRange, timeRegion, regions, fromStart, fromEnd, timeRegionColor: TimeRegionColorDefinition; @@ -143,7 +146,7 @@ export class TimeRegionManager { regions = []; - fromStart = moment(tRange.from); + fromStart = dateTime(tRange.from); fromStart.set('hour', 0); fromStart.set('minute', 0); fromStart.set('second', 0); @@ -160,7 +163,7 @@ export class TimeRegionManager { break; } - fromEnd = moment(fromStart); + fromEnd = dateTime(fromStart); if (hRange.from.h <= hRange.to.h) { fromEnd.add(hRange.to.h - hRange.from.h, 'hours'); diff --git a/public/app/plugins/panel/heatmap/rendering.ts b/public/app/plugins/panel/heatmap/rendering.ts index 91bf5ae85bb..ef146f2a4ec 100644 --- a/public/app/plugins/panel/heatmap/rendering.ts +++ b/public/app/plugins/panel/heatmap/rendering.ts @@ -1,6 +1,5 @@ import _ from 'lodash'; import $ from 'jquery'; -import moment from 'moment'; import * as d3 from 'd3'; import { appEvents, contextSrv } from 'app/core/core'; import * as ticksUtils from 'app/core/utils/ticks'; @@ -8,6 +7,7 @@ import { HeatmapTooltip } from './heatmap_tooltip'; import { mergeZeroBuckets } from './heatmap_data_converter'; import { getColorScale, getOpacityScale } from './color_scale'; import { GrafanaThemeType, getColorFromHexRgbOrName, getValueFormat } from '@grafana/ui'; +import { toUtc } from '@grafana/ui/src/utils/moment_wrapper'; const MIN_CARD_SIZE = 1, CARD_PADDING = 1, @@ -713,8 +713,8 @@ export class HeatmapRenderer { const timeTo = this.xScale.invert(Math.max(this.selection.x1, this.selection.x2) - this.yAxisWidth); this.ctrl.timeSrv.setTime({ - from: moment.utc(timeFrom), - to: moment.utc(timeTo), + from: toUtc(timeFrom), + to: toUtc(timeTo), }); } diff --git a/public/app/plugins/panel/heatmap/specs/heatmap_ctrl.test.ts b/public/app/plugins/panel/heatmap/specs/heatmap_ctrl.test.ts index a51be8eb723..3eb4eb38121 100644 --- a/public/app/plugins/panel/heatmap/specs/heatmap_ctrl.test.ts +++ b/public/app/plugins/panel/heatmap/specs/heatmap_ctrl.test.ts @@ -1,5 +1,5 @@ -import moment from 'moment'; import { HeatmapCtrl } from '../heatmap_ctrl'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('HeatmapCtrl', () => { const ctx = {} as any; @@ -32,7 +32,7 @@ describe('HeatmapCtrl', () => { }, ]; - ctx.ctrl.range = { from: moment().valueOf(), to: moment().valueOf() }; + ctx.ctrl.range = { from: dateTime().valueOf(), to: dateTime().valueOf() }; ctx.ctrl.onDataReceived(data); }); @@ -44,10 +44,10 @@ describe('HeatmapCtrl', () => { describe('when time series are inside range', () => { beforeEach(() => { const range = { - from: moment() + from: dateTime() .subtract(1, 'days') .valueOf(), - to: moment().valueOf(), + to: dateTime().valueOf(), }; const data = [ diff --git a/public/app/plugins/panel/singlestat/specs/singlestat.test.ts b/public/app/plugins/panel/singlestat/specs/singlestat.test.ts index 902d722f0ad..3f10d3ce9f6 100644 --- a/public/app/plugins/panel/singlestat/specs/singlestat.test.ts +++ b/public/app/plugins/panel/singlestat/specs/singlestat.test.ts @@ -1,5 +1,5 @@ import { SingleStatCtrl } from '../module'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; describe('SingleStatCtrl', () => { const ctx = {} as any; @@ -89,7 +89,7 @@ describe('SingleStatCtrl', () => { }); it('should set formatted value', () => { - expect(moment(ctx.data.valueFormatted).valueOf()).toBe(1505634997000); + expect(dateTime(ctx.data.valueFormatted).valueOf()).toBe(1505634997000); }); }); @@ -120,7 +120,7 @@ describe('SingleStatCtrl', () => { }); it('should set formatted value', () => { - expect(ctx.data.valueFormatted).toBe(moment(1505634997920).format('MM/DD/YYYY h:mm:ss a')); + expect(ctx.data.valueFormatted).toBe(dateTime(1505634997920).format('MM/DD/YYYY h:mm:ss a')); }); }); diff --git a/public/app/plugins/panel/table/renderer.ts b/public/app/plugins/panel/table/renderer.ts index c14e0312737..b138415eb0e 100644 --- a/public/app/plugins/panel/table/renderer.ts +++ b/public/app/plugins/panel/table/renderer.ts @@ -1,7 +1,7 @@ import _ from 'lodash'; -import moment from 'moment'; import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType, stringToJsRegex } from '@grafana/ui'; import { ColumnStyle } from '@grafana/ui/src/components/Table/TableCellBuilder'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export class TableRenderer { formatters: any[]; @@ -105,7 +105,7 @@ export class TableRenderer { v = parseInt(v, 10); } - let date = moment(v); + let date = dateTime(v); if (this.isUtc) { date = date.utc(); diff --git a/public/test/helpers/getQueryOptions.ts b/public/test/helpers/getQueryOptions.ts index 290c450b248..2d63e166776 100644 --- a/public/test/helpers/getQueryOptions.ts +++ b/public/test/helpers/getQueryOptions.ts @@ -1,11 +1,11 @@ import { DataQueryRequest, DataQuery } from '@grafana/ui'; -import moment from 'moment'; +import { dateTime } from '@grafana/ui/src/utils/moment_wrapper'; export function getQueryOptions( options: Partial> ): DataQueryRequest { const raw = { from: 'now', to: 'now-1h' }; - const range = { from: moment(), to: moment(), raw: raw }; + const range = { from: dateTime(), to: dateTime(), raw: raw }; const defaults: DataQueryRequest = { requestId: 'TEST', diff --git a/tslint.json b/tslint.json index 4c7ea71366c..472d74b1b3c 100644 --- a/tslint.json +++ b/tslint.json @@ -2,14 +2,18 @@ "rules": { "array-type": [true, "array-simple"], "arrow-return-shorthand": true, - "ban": [true, - {"name": "Array", "message": "tsstyle#array-constructor"} + "ban": [ + true, + { "name": "Array", "message": "tsstyle#array-constructor" } + // { "name": "moment", "message": "Use 'dateTime' instead." } ], - "ban-types": [true, + "ban-types": [ + true, ["Object", "Use {} instead."], ["String", "Use 'string' instead."], ["Number", "Use 'number' instead."], - ["Boolean", "Use 'boolean' instead."] + ["Boolean", "Use 'boolean' instead."], + ["Moment", "Use 'DateTime' instead."] ], "interface-name": [true, "never-prefix"], "no-string-throw": true, @@ -71,6 +75,7 @@ "allow-pascal-case" ], "use-isnan": true, - "whitespace": [true, "check-branch", "check-decl", "check-type", "check-preblock"] + "whitespace": [true, "check-branch", "check-decl", "check-type", "check-preblock"], + "import-blacklist": [true, "moment"] } }