瀏覽代碼

feat(timepicker2): worked on more rich time range support

Torkel Ödegaard 10 年之前
父節點
當前提交
a9812167d7

+ 108 - 0
public/app/core/utils/rangeutil.ts

@@ -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,
+}
+

+ 4 - 4
public/app/features/dashboard/timepicker/timepicker.ts

@@ -5,13 +5,13 @@ import _ = require('lodash');
 import moment = require('moment');
 import kbn = require('kbn');
 import dateMath = require('app/core/utils/datemath');
-import {TimeRange} from './timerange';
+import rangeUtil = require('app/core/utils/rangeutil');
 
 export class TimePickerCtrl {
 
   static defaults = {
     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'],
   };
 
@@ -81,7 +81,7 @@ export class TimePickerCtrl {
 
     if (this.timeSrv.time) {
       if (this.$scope.panel.now) {
-        model.rangeString = TimeRange.describeRelativeTime(this.timeSrv.time);
+        model.rangeString = rangeUtil.describeTimeRange(this.timeSrv.time);
       }
       else {
         model.rangeString = this.$scope.dashboard.formatDate(model.from.date, 'MMM D, YYYY HH:mm:ss') + ' to ' +
@@ -93,7 +93,7 @@ export class TimePickerCtrl {
   }
 
   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;
   }
 

+ 0 - 60
public/app/features/dashboard/timepicker/timerange.ts

@@ -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";
-  }
-}
-
-

+ 1 - 1
public/test/specs/core/utils/datemath_specs.ts

@@ -70,7 +70,7 @@ describe("DateMath", () => {
     });
   });
 
-  describe.only('rounding', () => {
+  describe('rounding', () => {
     var now;
     var anchored;
 

+ 34 - 0
public/test/specs/core/utils/rangeutil_specs.ts

@@ -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');
+    });
+
+
+  });
+
+});