mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(timepicker2): worked on more rich time range support
This commit is contained in:
108
public/app/core/utils/rangeutil.ts
Normal file
108
public/app/core/utils/rangeutil.ts
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import moment = require('moment');
|
||||||
|
import _ = require('lodash');
|
||||||
|
import angular = require('angular');
|
||||||
|
|
||||||
|
var spans = {
|
||||||
|
's': {display: 'second'},
|
||||||
|
'm': {display: 'minute'},
|
||||||
|
'h': {display: 'hour'},
|
||||||
|
'd': {display: 'day'},
|
||||||
|
'w': {display: 'week'},
|
||||||
|
'M': {display: 'month'},
|
||||||
|
'y': {display: 'year'},
|
||||||
|
};
|
||||||
|
|
||||||
|
var rangeOptions = [
|
||||||
|
{ from: 'now/d', to: 'now/d', display: 'Today', section: 0 },
|
||||||
|
{ from: 'now/w', to: 'now/w', display: 'This week', section: 0 },
|
||||||
|
{ from: 'now/d', to: 'now', display: 'The day so far', section: 0 },
|
||||||
|
{ from: 'now/w', to: 'now', display: 'Week to date', section: 0 },
|
||||||
|
{ from: 'now/M', to: 'now/M', display: 'This month', section: 0 },
|
||||||
|
{ from: 'now/y', to: 'now/y', display: 'This year', section: 0 },
|
||||||
|
|
||||||
|
{ from: 'now-1d/d', to: 'now-1d/d', display: 'Yesterday', section: 1 },
|
||||||
|
{ from: 'now-2d/d', to: 'now-2d/d', display: 'Day before yesterday', section: 1 },
|
||||||
|
{ from: 'now-7d/d', to: 'now-7d/d', display: 'This day last week', section: 1 },
|
||||||
|
{ from: 'now-1w/w', to: 'now-1w/w', display: 'Previous week', section: 1 },
|
||||||
|
{ from: 'now-1M/M', to: 'now-1M/M', display: 'Previous month', section: 1 },
|
||||||
|
{ from: 'now-1y/y', to: 'now-1y/y', display: 'Previous year', section: 1 },
|
||||||
|
|
||||||
|
{ from: 'now-5m', to: 'now', display: 'Last 5 minutes', section: 2 },
|
||||||
|
{ from: 'now-15m', to: 'now', display: 'Last 15 minutes', section: 2 },
|
||||||
|
{ from: 'now-30m', to: 'now', display: 'Last 30 minutes', section: 2 },
|
||||||
|
{ from: 'now-1h', to: 'now', display: 'Last 1 hour', section: 2 },
|
||||||
|
{ from: 'now-4h', to: 'now', display: 'Last 4 hours', section: 2 },
|
||||||
|
{ from: 'now-12h', to: 'now', display: 'Last 12 hours', section: 2 },
|
||||||
|
{ from: 'now-24h', to: 'now', display: 'Last 24 hours', section: 2 },
|
||||||
|
{ from: 'now-7d', to: 'now', display: 'Last 7 days', section: 2 },
|
||||||
|
|
||||||
|
{ from: 'now-30d', to: 'now', display: 'Last 30 days', section: 3 },
|
||||||
|
{ from: 'now-60d', to: 'now', display: 'Last 60 days', section: 3 },
|
||||||
|
{ from: 'now-90d', to: 'now', display: 'Last 90 days', section: 3 },
|
||||||
|
{ from: 'now-6M', to: 'now', display: 'Last 6 months', section: 3 },
|
||||||
|
{ from: 'now-1y', to: 'now', display: 'Last 1 year', section: 3 },
|
||||||
|
{ from: 'now-2y', to: 'now', display: 'Last 2 years', section: 3 },
|
||||||
|
{ from: 'now-5y', to: 'now', display: 'Last 5 years', section: 3 },
|
||||||
|
];
|
||||||
|
|
||||||
|
var rangeIndex = {};
|
||||||
|
_.each(rangeOptions, function (frame) {
|
||||||
|
rangeIndex[frame.from + ' to ' + frame.to] = frame;
|
||||||
|
});
|
||||||
|
|
||||||
|
function getRelativeTimesList(timepickerSettings) {
|
||||||
|
return _.map(timepickerSettings.time_options, function(duration: string) {
|
||||||
|
return describeTextRange(duration);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// handles expressions like
|
||||||
|
// 5m
|
||||||
|
// 5m to now/d
|
||||||
|
// now/d to now
|
||||||
|
// now/d
|
||||||
|
// if no to <expr> then to now is assumed
|
||||||
|
function describeTextRange(expr: string) {
|
||||||
|
let rangeExpr = 'now-' + expr + ' to now';
|
||||||
|
if (expr.indexOf('now') === 0) {
|
||||||
|
rangeExpr = expr + ' to now';
|
||||||
|
}
|
||||||
|
|
||||||
|
let opt = rangeIndex[rangeExpr];
|
||||||
|
if (opt) {
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt = {from: 'now-' + expr, to: 'now', display: 'Parse error'};
|
||||||
|
|
||||||
|
if (/^\d+\w$/.test(expr)) {
|
||||||
|
let unit = expr[expr.length - 1];
|
||||||
|
let amount = parseInt(expr.substring(0, expr.length - 1));
|
||||||
|
let span = spans[unit];
|
||||||
|
if (span) {
|
||||||
|
opt.display = 'Last ' + amount + ' ' + span.display;
|
||||||
|
if (amount > 1) {
|
||||||
|
opt.display += 's';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function describeTimeRange(range) {
|
||||||
|
var option = rangeIndex[range.from.toString() + ' to ' + range.to.toString()];
|
||||||
|
if (option) {
|
||||||
|
return option.display;
|
||||||
|
}
|
||||||
|
return "NA";
|
||||||
|
}
|
||||||
|
|
||||||
|
export = {
|
||||||
|
getRelativeTimesList: getRelativeTimesList,
|
||||||
|
describeTextRange: describeTextRange,
|
||||||
|
describeTimeRange: describeTimeRange,
|
||||||
|
}
|
||||||
|
|
||||||
@@ -5,13 +5,13 @@ import _ = require('lodash');
|
|||||||
import moment = require('moment');
|
import moment = require('moment');
|
||||||
import kbn = require('kbn');
|
import kbn = require('kbn');
|
||||||
import dateMath = require('app/core/utils/datemath');
|
import dateMath = require('app/core/utils/datemath');
|
||||||
import {TimeRange} from './timerange';
|
import rangeUtil = require('app/core/utils/rangeutil');
|
||||||
|
|
||||||
export class TimePickerCtrl {
|
export class TimePickerCtrl {
|
||||||
|
|
||||||
static defaults = {
|
static defaults = {
|
||||||
status : "Stable",
|
status : "Stable",
|
||||||
time_options : ['5m','15m','1h','6h','12h','24h','today', '2d','7d','30d'],
|
time_options : ['5m','15m','1h','6h','12h','24h','2d','7d','30d'],
|
||||||
refresh_intervals : ['5s','10s','30s','1m','5m','15m','30m','1h','2h','1d'],
|
refresh_intervals : ['5s','10s','30s','1m','5m','15m','30m','1h','2h','1d'],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ export class TimePickerCtrl {
|
|||||||
|
|
||||||
if (this.timeSrv.time) {
|
if (this.timeSrv.time) {
|
||||||
if (this.$scope.panel.now) {
|
if (this.$scope.panel.now) {
|
||||||
model.rangeString = TimeRange.describeRelativeTime(this.timeSrv.time);
|
model.rangeString = rangeUtil.describeTimeRange(this.timeSrv.time);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
model.rangeString = this.$scope.dashboard.formatDate(model.from.date, 'MMM D, YYYY HH:mm:ss') + ' to ' +
|
model.rangeString = this.$scope.dashboard.formatDate(model.from.date, 'MMM D, YYYY HH:mm:ss') + ' to ' +
|
||||||
@@ -93,7 +93,7 @@ export class TimePickerCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadTimeOptions() {
|
loadTimeOptions() {
|
||||||
this.$scope.timeOptions = TimeRange.getRelativeTimesList(this.$scope.panel);
|
this.$scope.timeOptions = rangeUtil.getRelativeTimesList(this.$scope.panel);
|
||||||
this.$scope.refreshMenuLeftSide = this.$scope.time.rangeString.length < 10;
|
this.$scope.refreshMenuLeftSide = this.$scope.time.rangeString.length < 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
///<reference path="../../../headers/common.d.ts" />
|
|
||||||
|
|
||||||
import _ = require('lodash');
|
|
||||||
import moment = require('moment');
|
|
||||||
|
|
||||||
var rangeOptions = [
|
|
||||||
{ from: 'now/d', to: 'now/d', display: 'Today', section: 0 },
|
|
||||||
{ from: 'now/w', to: 'now/w', display: 'This week', section: 0 },
|
|
||||||
|
|
||||||
{ from: 'now/d', to: 'now', display: 'The day so far', section: 0 },
|
|
||||||
{ from: 'now/w', to: 'now', display: 'Week to date', section: 0 },
|
|
||||||
// { from: 'now/M', to: 'now/M', display: 'This month', section: 0 },
|
|
||||||
// { from: 'now/y', to: 'now/y', display: 'This year', section: 0 },
|
|
||||||
//
|
|
||||||
// { from: 'now-1d/d', to: 'now-1d/d', display: 'Yesterday', section: 1 },
|
|
||||||
// { from: 'now-2d/d', to: 'now-2d/d', display: 'Day before yesterday', section: 1 },
|
|
||||||
// { from: 'now-7d/d', to: 'now-7d/d', display: 'This day last week', section: 1 },
|
|
||||||
// { from: 'now-1w/w', to: 'now-1w/w', display: 'Previous week', section: 1 },
|
|
||||||
// { from: 'now-1M/M', to: 'now-1M/M', display: 'Previous month', section: 1 },
|
|
||||||
// { from: 'now-1y/y', to: 'now-1y/y', display: 'Previous year', section: 1 },
|
|
||||||
|
|
||||||
{ from: 'now-5m', to: 'now', display: 'Last 5 minutes', section: 2 },
|
|
||||||
{ from: 'now-15m', to: 'now', display: 'Last 15 minutes', section: 2 },
|
|
||||||
{ from: 'now-30m', to: 'now', display: 'Last 30 minutes', section: 2 },
|
|
||||||
{ from: 'now-1h', to: 'now', display: 'Last 1 hour', section: 2 },
|
|
||||||
{ from: 'now-4h', to: 'now', display: 'Last 4 hours', section: 2 },
|
|
||||||
{ from: 'now-12h', to: 'now', display: 'Last 12 hours', section: 2 },
|
|
||||||
{ from: 'now-24h', to: 'now', display: 'Last 24 hours', section: 2 },
|
|
||||||
{ from: 'now-7d', to: 'now', display: 'Last 7 days', section: 2 },
|
|
||||||
|
|
||||||
{ from: 'now-30d', to: 'now', display: 'Last 30 days', section: 3 },
|
|
||||||
// { from: 'now-60d', to: 'now', display: 'Last 60 days', section: 3 },
|
|
||||||
// { from: 'now-90d', to: 'now', display: 'Last 90 days', section: 3 },
|
|
||||||
// { from: 'now-6M', to: 'now', display: 'Last 6 months', section: 3 },
|
|
||||||
// { from: 'now-1y', to: 'now', display: 'Last 1 year', section: 3 },
|
|
||||||
// { from: 'now-2y', to: 'now', display: 'Last 2 years', section: 3 },
|
|
||||||
// { from: 'now-5y', to: 'now', display: 'Last 5 years', section: 3 },
|
|
||||||
];
|
|
||||||
|
|
||||||
var rangeIndex = {};
|
|
||||||
_.each(rangeOptions, function (frame) {
|
|
||||||
rangeIndex[frame.from + ' to ' + frame.to] = frame;
|
|
||||||
});
|
|
||||||
|
|
||||||
export class TimeRange {
|
|
||||||
|
|
||||||
static getRelativeTimesList(timepickerSettings) {
|
|
||||||
return rangeOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
static describeRelativeTime(range) {
|
|
||||||
var option = rangeIndex[range.from.toString() + ' to ' + range.to.toString()];
|
|
||||||
if (option) {
|
|
||||||
return option.display;
|
|
||||||
}
|
|
||||||
return "NA";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ describe("DateMath", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.only('rounding', () => {
|
describe('rounding', () => {
|
||||||
var now;
|
var now;
|
||||||
var anchored;
|
var anchored;
|
||||||
|
|
||||||
|
|||||||
34
public/test/specs/core/utils/rangeutil_specs.ts
Normal file
34
public/test/specs/core/utils/rangeutil_specs.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'
|
||||||
|
|
||||||
|
import rangeUtil = require('app/core/utils/rangeutil')
|
||||||
|
import _ = require('lodash')
|
||||||
|
import moment = require('moment')
|
||||||
|
|
||||||
|
describe("rangeUtil", () => {
|
||||||
|
|
||||||
|
describe("Can get range explained", () => {
|
||||||
|
|
||||||
|
it('should handle simple old expression with only amount and unit', () => {
|
||||||
|
var info = rangeUtil.describeTextRange('5m');
|
||||||
|
expect(info.display).to.be('Last 5 minutes')
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have singular when amount is 1', () => {
|
||||||
|
var info = rangeUtil.describeTextRange('1h');
|
||||||
|
expect(info.display).to.be('Last 1 hour')
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle now/d', () => {
|
||||||
|
var info = rangeUtil.describeTextRange('now/d');
|
||||||
|
expect(info.display).to.be('The day so far');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle now/w', () => {
|
||||||
|
var info = rangeUtil.describeTextRange('now/w');
|
||||||
|
expect(info.display).to.be('Week to date');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user