From eb06b1d27282ac21188956b65a5a970ddc44dd98 Mon Sep 17 00:00:00 2001 From: Gilligan Markham Date: Wed, 14 Nov 2018 15:57:34 -0800 Subject: [PATCH] Added ability to set a time override on a per-query basis. --- Gruntfile.js | 3 + dist/beans/request/metric_query.d.ts | 4 +- dist/beans/request/metric_query.js | 4 +- dist/beans/request/metric_query.js.map | 2 +- dist/beans/request/metric_query.ts | 6 +- dist/beans/request/target.d.ts | 8 ++ dist/beans/request/target.js | 27 +++- dist/beans/request/target.js.map | 2 +- dist/beans/request/target.ts | 29 +++++ dist/core/request/query_builder.js | 9 +- dist/core/request/query_builder.js.map | 2 +- dist/core/request/query_builder.ts | 4 +- dist/directives/timepicker.d.ts | 46 +++++++ dist/directives/timepicker.js | 148 +++++++++++++++++++++ dist/directives/timepicker.js.map | 1 + dist/directives/timepicker.ts | 162 +++++++++++++++++++++++ dist/module.js | 10 +- dist/module.js.map | 2 +- dist/module.ts | 4 +- dist/package.json | 8 +- dist/partials/query.editor.html | 1 + dist/partials/time.override.editor.html | 20 +++ dist/partials/timepicker.html | 56 ++++++++ dist/utils/moment.shim.d.ts | 8 ++ dist/utils/rangeutil.d.ts | 8 ++ dist/utils/rangeutil.js | 147 +++++++++++++++++++++ dist/utils/rangeutil.js.map | 1 + dist/utils/rangeutil.ts | 163 ++++++++++++++++++++++++ package.json | 8 +- src/beans/request/metric_query.ts | 6 +- src/beans/request/target.ts | 29 +++++ src/core/request/query_builder.ts | 4 +- src/directives/timepicker.ts | 162 +++++++++++++++++++++++ src/module.ts | 4 +- src/partials/query.editor.html | 1 + src/partials/time.override.editor.html | 20 +++ src/partials/timepicker.html | 56 ++++++++ src/utils/moment.shim.d.ts | 8 ++ src/utils/rangeutil.ts | 163 ++++++++++++++++++++++++ tsconfig.json | 8 ++ 40 files changed, 1326 insertions(+), 28 deletions(-) create mode 100644 dist/directives/timepicker.d.ts create mode 100644 dist/directives/timepicker.js create mode 100644 dist/directives/timepicker.js.map create mode 100644 dist/directives/timepicker.ts create mode 100644 dist/partials/time.override.editor.html create mode 100644 dist/partials/timepicker.html create mode 100644 dist/utils/moment.shim.d.ts create mode 100644 dist/utils/rangeutil.d.ts create mode 100644 dist/utils/rangeutil.js create mode 100644 dist/utils/rangeutil.js.map create mode 100644 dist/utils/rangeutil.ts create mode 100644 src/directives/timepicker.ts create mode 100644 src/partials/time.override.editor.html create mode 100644 src/partials/timepicker.html create mode 100644 src/utils/moment.shim.d.ts create mode 100644 src/utils/rangeutil.ts create mode 100644 tsconfig.json diff --git a/Gruntfile.js b/Gruntfile.js index 2b60b603..e3562da8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -61,12 +61,15 @@ module.exports = function (grunt) { ], dest: "dist/", options: { + moduleResolution: "node", module: "system", target: "es5", rootDir: "dist/", + allowSyntheticDefaultImports: true, keepDirectoryHierarchy: false, declaration: true, emitDecoratorMetadata: true, + esModuleInterop: true, experimentalDecorators: true, sourceMap: true, noImplicitAny: false diff --git a/dist/beans/request/metric_query.d.ts b/dist/beans/request/metric_query.d.ts index 1ec8f7ea..19759d97 100644 --- a/dist/beans/request/metric_query.d.ts +++ b/dist/beans/request/metric_query.d.ts @@ -4,5 +4,7 @@ export declare class MetricQuery { limit: number; aggregators: any[]; group_by: any[]; - constructor(name: string, tags: any, aggregators: any[], group_by: any[]); + start_absolute: number; + end_absolute: number; + constructor(name: string, tags: any, aggregators: any[], group_by: any[], start_absolute: number, end_absolute: number); } diff --git a/dist/beans/request/metric_query.js b/dist/beans/request/metric_query.js index 04211bd3..6a17d992 100644 --- a/dist/beans/request/metric_query.js +++ b/dist/beans/request/metric_query.js @@ -6,12 +6,14 @@ System.register([], function (exports_1, context_1) { setters: [], execute: function () { MetricQuery = (function () { - function MetricQuery(name, tags, aggregators, group_by) { + function MetricQuery(name, tags, aggregators, group_by, start_absolute, end_absolute) { this.limit = 0; this.name = name; this.tags = tags; this.aggregators = aggregators; this.group_by = group_by; + this.start_absolute = start_absolute; + this.end_absolute = end_absolute; } return MetricQuery; }()); diff --git a/dist/beans/request/metric_query.js.map b/dist/beans/request/metric_query.js.map index 17260808..21fac841 100644 --- a/dist/beans/request/metric_query.js.map +++ b/dist/beans/request/metric_query.js.map @@ -1 +1 @@ -{"version":3,"file":"metric_query.js","sourceRoot":"","sources":["metric_query.ts"],"names":[],"mappings":";;;;;;;YAAA;gBAOI,qBAAY,IAAY,EAAE,IAAS,EAAE,WAAkB,EAAE,QAAe;oBAJjE,UAAK,GAAW,CAAC,CAAC;oBAKrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;oBACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;oBACjB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;oBAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBAC7B,CAAC;gBACL,kBAAC;YAAD,CAAC,AAbD,IAaC;;QACD,CAAC"} \ No newline at end of file +{"version":3,"file":"metric_query.js","sourceRoot":"","sources":["metric_query.ts"],"names":[],"mappings":";;;;;;;YAAA;gBASI,qBAAY,IAAY,EAAE,IAAS,EAAE,WAAkB,EAAE,QAAe,EAAE,cAAsB,EAAE,YAAoB;oBAN/G,UAAK,GAAW,CAAC,CAAC;oBAOrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;oBACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;oBACjB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;oBAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;oBACzB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;oBACrC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;gBACrC,CAAC;gBACL,kBAAC;YAAD,CAAC,AAjBD,IAiBC;;QACD,CAAC"} \ No newline at end of file diff --git a/dist/beans/request/metric_query.ts b/dist/beans/request/metric_query.ts index 91e05121..38abe7a9 100644 --- a/dist/beans/request/metric_query.ts +++ b/dist/beans/request/metric_query.ts @@ -4,11 +4,15 @@ export class MetricQuery { public limit: number = 0; public aggregators: any[]; public group_by: any[]; + public start_absolute: number; + public end_absolute: number; - constructor(name: string, tags: any, aggregators: any[], group_by: any[]) { + constructor(name: string, tags: any, aggregators: any[], group_by: any[], start_absolute: number, end_absolute: number) { this.name = name; this.tags = tags; this.aggregators = aggregators; this.group_by = group_by; + this.start_absolute = start_absolute; + this.end_absolute = end_absolute; } } diff --git a/dist/beans/request/target.d.ts b/dist/beans/request/target.d.ts index 142d9614..19631520 100644 --- a/dist/beans/request/target.d.ts +++ b/dist/beans/request/target.d.ts @@ -1,7 +1,14 @@ +import { Moment } from "moment"; import { Aggregator } from "../aggregators/aggregator"; import { GroupBy } from "./group_by"; +export interface TimeRange { + from: Moment | string; + to: Moment | string; +} export declare class KairosDBTarget { static fromObject(object: any): KairosDBTarget; + static startTime(target: KairosDBTarget): number; + static endTime(target: KairosDBTarget): number; metricName: string; alias: string; tags: { @@ -9,5 +16,6 @@ export declare class KairosDBTarget { }; groupBy: GroupBy; aggregators: Aggregator[]; + timeRange: TimeRange; asString(): string; } diff --git a/dist/beans/request/target.js b/dist/beans/request/target.js index c59fa1fa..2f978707 100644 --- a/dist/beans/request/target.js +++ b/dist/beans/request/target.js @@ -1,9 +1,12 @@ -System.register(["../aggregators/aggregators", "./group_by"], function (exports_1, context_1) { +System.register(["app/core/utils/datemath", "../aggregators/aggregators", "./group_by"], function (exports_1, context_1) { "use strict"; - var Aggregators, group_by_1, KairosDBTarget; + var dateMath, Aggregators, group_by_1, KairosDBTarget; var __moduleName = context_1 && context_1.id; return { setters: [ + function (dateMath_1) { + dateMath = dateMath_1; + }, function (Aggregators_1) { Aggregators = Aggregators_1; }, @@ -19,6 +22,7 @@ System.register(["../aggregators/aggregators", "./group_by"], function (exports_ this.tags = {}; this.groupBy = new group_by_1.GroupBy(); this.aggregators = []; + this.timeRange = undefined; } KairosDBTarget.fromObject = function (object) { var rval = new KairosDBTarget(); @@ -27,8 +31,27 @@ System.register(["../aggregators/aggregators", "./group_by"], function (exports_ rval.tags = object.tags || {}; rval.groupBy = group_by_1.GroupBy.fromObject(object.groupBy); rval.aggregators = (object.aggregators || []).map(function (val) { return Aggregators.fromObject(val); }); + rval.timeRange = object.timeRange; return rval; }; + KairosDBTarget.startTime = function (target) { + if (target.timeRange) { + var startMoment = dateMath.parse(target.timeRange.from); + if (startMoment) { + return startMoment.unix() * 1000; + } + } + return undefined; + }; + KairosDBTarget.endTime = function (target) { + if (target.timeRange) { + var endMoment = dateMath.parse(target.timeRange.to); + if (endMoment) { + return endMoment.unix() * 1000; + } + } + return undefined; + }; KairosDBTarget.prototype.asString = function () { var _this = this; var str = "SELECT "; diff --git a/dist/beans/request/target.js.map b/dist/beans/request/target.js.map index 477df388..a233f453 100644 --- a/dist/beans/request/target.js.map +++ b/dist/beans/request/target.js.map @@ -1 +1 @@ -{"version":3,"file":"target.js","sourceRoot":"","sources":["target.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"target.js","sourceRoot":"","sources":["target.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/beans/request/target.ts b/dist/beans/request/target.ts index 6a420087..3cedc612 100644 --- a/dist/beans/request/target.ts +++ b/dist/beans/request/target.ts @@ -1,8 +1,15 @@ +import * as dateMath from "app/core/utils/datemath"; +import {Moment} from "moment"; import {Aggregator} from "../aggregators/aggregator"; import * as Aggregators from "../aggregators/aggregators"; import {AggregatorParameter} from "../aggregators/parameters/aggregator_parameter"; import {GroupBy} from "./group_by"; +export interface TimeRange { + from: Moment | string; + to: Moment | string; +} + export class KairosDBTarget { public static fromObject(object: any): KairosDBTarget { const rval = new KairosDBTarget(); @@ -12,14 +19,36 @@ export class KairosDBTarget { rval.groupBy = GroupBy.fromObject(object.groupBy); rval.aggregators = (object.aggregators || []).map( (val) => Aggregators.fromObject(val)); + rval.timeRange = object.timeRange; return rval; } + public static startTime(target: KairosDBTarget): number { + if (target.timeRange) { + const startMoment: Moment = dateMath.parse(target.timeRange.from); + if (startMoment) { + return startMoment.unix() * 1000; + } + } + return undefined; + } + + public static endTime(target: KairosDBTarget): number { + if (target.timeRange) { + const endMoment: Moment = dateMath.parse(target.timeRange.to); + if (endMoment) { + return endMoment.unix() * 1000; + } + } + return undefined; + } + public metricName: string = undefined; public alias: string = undefined; public tags: {[key: string]: string[]} = {}; public groupBy: GroupBy = new GroupBy(); public aggregators: Aggregator[] = []; + public timeRange: TimeRange = undefined; public asString(): string { let str = "SELECT "; diff --git a/dist/core/request/query_builder.js b/dist/core/request/query_builder.js index 420d4c1a..d6d6b2fa 100644 --- a/dist/core/request/query_builder.js +++ b/dist/core/request/query_builder.js @@ -1,6 +1,6 @@ -System.register(["lodash", "../../beans/request/datapoints_query", "../../beans/request/metric_query", "../../utils/templating_utils", "./group_bys_builder", "./parameter_object_builder", "./sampling_converter", "./sampling_parameter_converter"], function (exports_1, context_1) { +System.register(["lodash", "../../beans/request/datapoints_query", "../../beans/request/metric_query", "../../beans/request/target", "../../utils/templating_utils", "./group_bys_builder", "./parameter_object_builder", "./sampling_converter", "./sampling_parameter_converter"], function (exports_1, context_1) { "use strict"; - var lodash_1, datapoints_query_1, metric_query_1, templating_utils_1, group_bys_builder_1, parameter_object_builder_1, sampling_converter_1, sampling_parameter_converter_1, KairosDBQueryBuilder; + var lodash_1, datapoints_query_1, metric_query_1, target_1, templating_utils_1, group_bys_builder_1, parameter_object_builder_1, sampling_converter_1, sampling_parameter_converter_1, KairosDBQueryBuilder; var __moduleName = context_1 && context_1.id; return { setters: [ @@ -13,6 +13,9 @@ System.register(["lodash", "../../beans/request/datapoints_query", "../../beans/ function (metric_query_1_1) { metric_query_1 = metric_query_1_1; }, + function (target_1_1) { + target_1 = target_1_1; + }, function (templating_utils_1_1) { templating_utils_1 = templating_utils_1_1; }, @@ -70,7 +73,7 @@ System.register(["lodash", "../../beans/request/datapoints_query", "../../beans/ }; KairosDBQueryBuilder.prototype.buildMetricQuery = function (target, defaultInterval) { var _this = this; - return new metric_query_1.MetricQuery(target.metricName, this.unpackTags(lodash_1.default.pickBy(target.tags, function (tagValues) { return tagValues.length; })), target.aggregators.map(function (aggregator) { return _this.convertAggregatorToQueryObject(aggregator, defaultInterval); }), this.groupBysBuilder.build(target.groupBy)); + return new metric_query_1.MetricQuery(target.metricName, this.unpackTags(lodash_1.default.pickBy(target.tags, function (tagValues) { return tagValues.length; })), target.aggregators.map(function (aggregator) { return _this.convertAggregatorToQueryObject(aggregator, defaultInterval); }), this.groupBysBuilder.build(target.groupBy), target_1.KairosDBTarget.startTime(target), target_1.KairosDBTarget.endTime(target)); }; KairosDBQueryBuilder.prototype.unpackTags = function (tags) { var _this = this; diff --git a/dist/core/request/query_builder.js.map b/dist/core/request/query_builder.js.map index 2be42c72..2b75541d 100644 --- a/dist/core/request/query_builder.js.map +++ b/dist/core/request/query_builder.js.map @@ -1 +1 @@ -{"version":3,"file":"query_builder.js","sourceRoot":"","sources":["query_builder.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"query_builder.js","sourceRoot":"","sources":["query_builder.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/core/request/query_builder.ts b/dist/core/request/query_builder.ts index f61cbdc1..253c2af3 100644 --- a/dist/core/request/query_builder.ts +++ b/dist/core/request/query_builder.ts @@ -63,7 +63,9 @@ export class KairosDBQueryBuilder { target.metricName, this.unpackTags(_.pickBy(target.tags, (tagValues) => tagValues.length)), target.aggregators.map((aggregator) => this.convertAggregatorToQueryObject(aggregator, defaultInterval)), - this.groupBysBuilder.build(target.groupBy) + this.groupBysBuilder.build(target.groupBy), + KairosDBTarget.startTime(target), + KairosDBTarget.endTime(target) ); } diff --git a/dist/directives/timepicker.d.ts b/dist/directives/timepicker.d.ts new file mode 100644 index 00000000..09007041 --- /dev/null +++ b/dist/directives/timepicker.d.ts @@ -0,0 +1,46 @@ +import { KairosDBTarget } from "../beans/request/target"; +export declare class TimePickerCtrl { + private $scope; + private $rootScope; + private timeSrv; + static tooltipFormat: string; + static defaults: { + time_options: string[]; + refresh_intervals: string[]; + }; + dashboard: any; + query: KairosDBTarget; + panel: any; + absolute: any; + timeRaw: any; + editTimeRaw: any; + tooltip: string; + rangeString: string; + timeOptions: any; + refresh: any; + isUtc: boolean; + firstDayOfWeek: number; + isOpen: boolean; + isAbsolute: boolean; + constructor($scope: any, $rootScope: any, timeSrv: any); + onRefresh(): void; + openDropdown(): void; + closeDropdown(): void; + absoluteFromChanged(): void; + absoluteToChanged(): void; + getAbsoluteMomentForTimezone(jsDate: any): any; + setRelativeFilter(timespan: any): void; + enableOverride(): void; + disableOverride(): void; +} +export declare function TimePickerDirective(): { + restrict: string; + templateUrl: string; + controller: typeof TimePickerCtrl; + bindToController: boolean; + controllerAs: string; + scope: { + dashboard: string; + query: string; + }; +}; diff --git a/dist/directives/timepicker.js b/dist/directives/timepicker.js new file mode 100644 index 00000000..142bdfcc --- /dev/null +++ b/dist/directives/timepicker.js @@ -0,0 +1,148 @@ +System.register(["angular", "app/core/utils/datemath", "lodash", "moment", "../utils/rangeutil"], function (exports_1, context_1) { + "use strict"; + var angular_1, dateMath, lodash_1, moment_1, rangeUtil, TimePickerCtrl; + var __moduleName = context_1 && context_1.id; + function TimePickerDirective() { + return { + restrict: "E", + templateUrl: "public/plugins/grafana-kairosdb-datasource/partials/timepicker.html", + controller: TimePickerCtrl, + bindToController: true, + controllerAs: "ctrl", + scope: { + dashboard: "=", + query: "=", + }, + }; + } + exports_1("TimePickerDirective", TimePickerDirective); + return { + setters: [ + function (angular_1_1) { + angular_1 = angular_1_1; + }, + function (dateMath_1) { + dateMath = dateMath_1; + }, + function (lodash_1_1) { + lodash_1 = lodash_1_1; + }, + function (moment_1_1) { + moment_1 = moment_1_1; + }, + function (rangeUtil_1) { + rangeUtil = rangeUtil_1; + } + ], + execute: function () { + TimePickerCtrl = (function () { + function TimePickerCtrl($scope, $rootScope, timeSrv) { + var _this = this; + this.$scope = $scope; + this.$rootScope = $rootScope; + this.timeSrv = timeSrv; + this.$scope.ctrl = this; + $scope.$parent.$watch("timeOverridden", function (newValue, oldValue) { + if (newValue !== undefined) { + if (newValue) { + _this.enableOverride(); + } + else { + _this.disableOverride(); + } + } + }); + $rootScope.onAppEvent("closeTimepicker", this.openDropdown.bind(this), $scope); + this.dashboard.on("refresh", this.onRefresh.bind(this), $scope); + this.panel = this.dashboard.timepicker; + lodash_1.default.defaults(this.panel, TimePickerCtrl.defaults); + this.firstDayOfWeek = moment_1.default.localeData().firstDayOfWeek(); + this.onRefresh(); + } + TimePickerCtrl.prototype.onRefresh = function () { + var timeRaw = angular_1.default.copy(this.query.timeRange); + if (!timeRaw) { + timeRaw = this.timeSrv.timeRange().raw; + } + if (!this.dashboard.isTimezoneUtc()) { + if (moment_1.default.isMoment(timeRaw.from)) { + timeRaw.from.local(); + } + if (moment_1.default.isMoment(timeRaw.to)) { + timeRaw.to.local(); + } + this.isUtc = false; + } + else { + this.isUtc = true; + } + var fromMoment = dateMath.parse(timeRaw.from); + var toMoment = dateMath.parse(timeRaw.to); + this.rangeString = rangeUtil.describeTimeRange(timeRaw); + this.absolute = { fromJs: fromMoment.toDate(), toJs: toMoment.toDate() }; + this.tooltip = this.dashboard.formatDate(fromMoment) + "
to
"; + this.tooltip += this.dashboard.formatDate(toMoment); + this.timeRaw = timeRaw; + this.isAbsolute = moment_1.default.isMoment(this.timeRaw.to); + }; + TimePickerCtrl.prototype.openDropdown = function () { + if (this.isOpen) { + this.closeDropdown(); + return; + } + this.onRefresh(); + this.editTimeRaw = this.timeRaw; + this.timeOptions = rangeUtil.getRelativeTimesList(this.panel, this.rangeString); + this.refresh = { + value: this.dashboard.refresh, + options: lodash_1.default.map(this.panel.refresh_intervals, function (interval) { + return { text: interval, value: interval }; + }), + }; + this.refresh.options.unshift({ text: "off" }); + this.isOpen = true; + this.$rootScope.appEvent("timepickerOpen"); + }; + TimePickerCtrl.prototype.closeDropdown = function () { + this.isOpen = false; + this.onRefresh(); + this.$rootScope.appEvent("timepickerClosed"); + }; + TimePickerCtrl.prototype.absoluteFromChanged = function () { + this.editTimeRaw.from = this.getAbsoluteMomentForTimezone(this.absolute.fromJs); + }; + TimePickerCtrl.prototype.absoluteToChanged = function () { + this.editTimeRaw.to = this.getAbsoluteMomentForTimezone(this.absolute.toJs); + }; + TimePickerCtrl.prototype.getAbsoluteMomentForTimezone = function (jsDate) { + return this.dashboard.isTimezoneUtc() ? moment_1.default(jsDate).utc() : moment_1.default(jsDate); + }; + TimePickerCtrl.prototype.setRelativeFilter = function (timespan) { + var range = { from: timespan.from, to: timespan.to }; + if (this.panel.nowDelay && range.to === "now") { + range.to = "now-" + this.panel.nowDelay; + } + this.query.timeRange = range; + this.closeDropdown(); + }; + TimePickerCtrl.prototype.enableOverride = function () { + var timeRaw = this.timeSrv.timeRange().raw; + this.query.timeRange = { from: timeRaw.from, to: timeRaw.to }; + this.onRefresh(); + }; + TimePickerCtrl.prototype.disableOverride = function () { + this.query.timeRange = undefined; + this.onRefresh(); + }; + TimePickerCtrl.tooltipFormat = "MMM D, YYYY HH:mm:ss"; + TimePickerCtrl.defaults = { + time_options: ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"], + refresh_intervals: ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], + }; + return TimePickerCtrl; + }()); + exports_1("TimePickerCtrl", TimePickerCtrl); + } + }; +}); +//# sourceMappingURL=timepicker.js.map \ No newline at end of file diff --git a/dist/directives/timepicker.js.map b/dist/directives/timepicker.js.map new file mode 100644 index 00000000..94827be2 --- /dev/null +++ b/dist/directives/timepicker.js.map @@ -0,0 +1 @@ +{"version":3,"file":"timepicker.js","sourceRoot":"","sources":["timepicker.ts"],"names":[],"mappings":";;;;IAqJA;QACE,OAAO;YACL,QAAQ,EAAE,GAAG;YACb,WAAW,EAAE,qEAAqE;YAClF,UAAU,EAAE,cAAc;YAC1B,gBAAgB,EAAE,IAAI;YACtB,YAAY,EAAE,MAAM;YACpB,KAAK,EAAE;gBACL,SAAS,EAAE,GAAG;gBACd,KAAK,EAAE,GAAG;aACX;SACF,CAAC;IACJ,CAAC;;;;;;;;;;;;;;;;;;;;;;gBAlIC,wBAAoB,MAAM,EAAU,UAAU,EAAU,OAAO;oBAA/D,iBAwBC;oBAxBmB,WAAM,GAAN,MAAM,CAAA;oBAAU,eAAU,GAAV,UAAU,CAAA;oBAAU,YAAO,GAAP,OAAO,CAAA;oBAC7D,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;oBAExB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,UAAC,QAAQ,EAAE,QAAQ;wBACzD,IAAI,QAAQ,KAAK,SAAS,EAAE;4BACxB,IAAI,QAAQ,EAAE;gCACV,KAAI,CAAC,cAAc,EAAE,CAAC;6BACzB;iCAAM;gCACH,KAAI,CAAC,eAAe,EAAE,CAAC;6BAC1B;yBACJ;oBACH,CAAC,CAAC,CAAC;oBAEH,UAAU,CAAC,UAAU,CAAC,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;oBAE/E,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;oBAGhE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;oBACvC,gBAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;oBAChD,IAAI,CAAC,cAAc,GAAG,gBAAM,CAAC,UAAU,EAAE,CAAC,cAAc,EAAE,CAAC;oBAG3D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,CAAC;gBAEM,kCAAS,GAAhB;oBACE,IAAI,OAAO,GAAG,iBAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;oBAEjD,IAAI,CAAC,OAAO,EAAE;wBACZ,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC;qBACxC;oBAED,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE;wBACnC,IAAI,gBAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;4BACjC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;yBACtB;wBACD,IAAI,gBAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;4BAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;yBACpB;wBACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;qBACpB;yBAAM;wBACL,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;qBACnB;oBAED,IAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAChD,IAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBAE5C,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;oBACxD,IAAI,CAAC,QAAQ,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;oBACzE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC;oBACrE,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;oBACvB,IAAI,CAAC,UAAU,GAAG,gBAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACrD,CAAC;gBAEM,qCAAY,GAAnB;oBACE,IAAI,IAAI,CAAC,MAAM,EAAE;wBACf,IAAI,CAAC,aAAa,EAAE,CAAC;wBACrB,OAAO;qBACR;oBAED,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;oBAChC,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;oBAChF,IAAI,CAAC,OAAO,GAAG;wBACb,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO;wBAC7B,OAAO,EAAE,gBAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,UAAC,QAAa;4BACzD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;wBAC7C,CAAC,CAAC;qBACH,CAAC;oBAEF,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC9C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;oBACnB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;gBAC7C,CAAC;gBAEM,sCAAa,GAApB;oBACE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;oBACpB,IAAI,CAAC,SAAS,EAAE,CAAC;oBACjB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;gBAC/C,CAAC;gBAEM,4CAAmB,GAA1B;oBACE,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAClF,CAAC;gBAEM,0CAAiB,GAAxB;oBACE,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC9E,CAAC;gBAEM,qDAA4B,GAAnC,UAAoC,MAAM;oBACxC,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,gBAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,gBAAM,CAAC,MAAM,CAAC,CAAC;gBAChF,CAAC;gBAEM,0CAAiB,GAAxB,UAAyB,QAAQ;oBAC/B,IAAM,KAAK,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;oBAEvD,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,KAAK,KAAK,EAAE;wBAC7C,KAAK,CAAC,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;qBACzC;oBAED,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;oBAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,CAAC;gBAEM,uCAAc,GAArB;oBACE,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC;oBAC7C,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAC,CAAC;oBAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,CAAC;gBAEM,wCAAe,GAAtB;oBACE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;oBACjC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,CAAC;gBAzIa,4BAAa,GAAG,sBAAsB,CAAC;gBACvC,uBAAQ,GAAG;oBACvB,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;oBACxE,iBAAiB,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;iBACpF,CAAC;gBAsIJ,qBAAC;aAAA,AA3ID;;QA0JA,CAAC"} \ No newline at end of file diff --git a/dist/directives/timepicker.ts b/dist/directives/timepicker.ts new file mode 100644 index 00000000..98253a01 --- /dev/null +++ b/dist/directives/timepicker.ts @@ -0,0 +1,162 @@ +import angular from "angular"; +import * as dateMath from "app/core/utils/datemath"; +import _ from "lodash"; +import moment from "moment"; + +import {KairosDBTarget} from "../beans/request/target"; +import * as rangeUtil from "../utils/rangeutil"; + +export class TimePickerCtrl { + public static tooltipFormat = "MMM D, YYYY HH:mm:ss"; + public static defaults = { + time_options: ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"], + refresh_intervals: ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], + }; + + public dashboard: any; + public query: KairosDBTarget; + public panel: any; + public absolute: any; + public timeRaw: any; + public editTimeRaw: any; + public tooltip: string; + public rangeString: string; + public timeOptions: any; + public refresh: any; + public isUtc: boolean; + public firstDayOfWeek: number; + public isOpen: boolean; + public isAbsolute: boolean; + + /** @ngInject */ + constructor(private $scope, private $rootScope, private timeSrv) { + this.$scope.ctrl = this; + + $scope.$parent.$watch("timeOverridden", (newValue, oldValue) => { + if (newValue !== undefined) { + if (newValue) { + this.enableOverride(); + } else { + this.disableOverride(); + } + } + }); + + $rootScope.onAppEvent("closeTimepicker", this.openDropdown.bind(this), $scope); + + this.dashboard.on("refresh", this.onRefresh.bind(this), $scope); + + // init options + this.panel = this.dashboard.timepicker; + _.defaults(this.panel, TimePickerCtrl.defaults); + this.firstDayOfWeek = moment.localeData().firstDayOfWeek(); + + // init time stuff + this.onRefresh(); + } + + public onRefresh() { + let timeRaw = angular.copy(this.query.timeRange); + + if (!timeRaw) { + timeRaw = this.timeSrv.timeRange().raw; + } + + if (!this.dashboard.isTimezoneUtc()) { + if (moment.isMoment(timeRaw.from)) { + timeRaw.from.local(); + } + if (moment.isMoment(timeRaw.to)) { + timeRaw.to.local(); + } + this.isUtc = false; + } else { + this.isUtc = true; + } + + const fromMoment = dateMath.parse(timeRaw.from); + const toMoment = dateMath.parse(timeRaw.to); + + this.rangeString = rangeUtil.describeTimeRange(timeRaw); + this.absolute = { fromJs: fromMoment.toDate(), toJs: toMoment.toDate() }; + this.tooltip = this.dashboard.formatDate(fromMoment) + "
to
"; + this.tooltip += this.dashboard.formatDate(toMoment); + this.timeRaw = timeRaw; + this.isAbsolute = moment.isMoment(this.timeRaw.to); + } + + public openDropdown() { + if (this.isOpen) { + this.closeDropdown(); + return; + } + + this.onRefresh(); + this.editTimeRaw = this.timeRaw; + this.timeOptions = rangeUtil.getRelativeTimesList(this.panel, this.rangeString); + this.refresh = { + value: this.dashboard.refresh, + options: _.map(this.panel.refresh_intervals, (interval: any) => { + return { text: interval, value: interval }; + }), + }; + + this.refresh.options.unshift({ text: "off" }); + this.isOpen = true; + this.$rootScope.appEvent("timepickerOpen"); + } + + public closeDropdown() { + this.isOpen = false; + this.onRefresh(); + this.$rootScope.appEvent("timepickerClosed"); + } + + public absoluteFromChanged() { + this.editTimeRaw.from = this.getAbsoluteMomentForTimezone(this.absolute.fromJs); + } + + public absoluteToChanged() { + this.editTimeRaw.to = this.getAbsoluteMomentForTimezone(this.absolute.toJs); + } + + public getAbsoluteMomentForTimezone(jsDate) { + return this.dashboard.isTimezoneUtc() ? moment(jsDate).utc() : moment(jsDate); + } + + public setRelativeFilter(timespan) { + const range = { from: timespan.from, to: timespan.to }; + + if (this.panel.nowDelay && range.to === "now") { + range.to = "now-" + this.panel.nowDelay; + } + + this.query.timeRange = range; + this.closeDropdown(); + } + + public enableOverride() { + const timeRaw = this.timeSrv.timeRange().raw; + this.query.timeRange = {from: timeRaw.from, to: timeRaw.to}; + this.onRefresh(); + } + + public disableOverride() { + this.query.timeRange = undefined; + this.onRefresh(); + } +} + +export function TimePickerDirective() { + return { + restrict: "E", + templateUrl: "public/plugins/grafana-kairosdb-datasource/partials/timepicker.html", + controller: TimePickerCtrl, + bindToController: true, + controllerAs: "ctrl", + scope: { + dashboard: "=", + query: "=", + }, + }; +} diff --git a/dist/module.js b/dist/module.js index 3263ff59..ea58ed0c 100644 --- a/dist/module.js +++ b/dist/module.js @@ -1,6 +1,6 @@ -System.register(["angular", "./core/config_ctrl", "./core/datasource", "./core/query_ctrl", "./directives/aggregator", "./directives/aggregator_editor", "./directives/aggregators", "./directives/group_by/group_by_tags", "./directives/group_by/group_by_time", "./directives/group_by/group_by_value", "./directives/metric_name_field", "./directives/tag_input", "./directives/tags_select"], function (exports_1, context_1) { +System.register(["angular", "./core/config_ctrl", "./core/datasource", "./core/query_ctrl", "./directives/aggregator", "./directives/aggregator_editor", "./directives/aggregators", "./directives/group_by/group_by_tags", "./directives/group_by/group_by_time", "./directives/group_by/group_by_value", "./directives/metric_name_field", "./directives/tag_input", "./directives/tags_select", "./directives/timepicker"], function (exports_1, context_1) { "use strict"; - var angular_1, config_ctrl_1, datasource_1, query_ctrl_1, aggregator_1, aggregator_editor_1, aggregators_1, group_by_tags_1, group_by_time_1, group_by_value_1, metric_name_field_1, tag_input_1, tags_select_1, KairosDBQueryOptionsCtrl; + var angular_1, config_ctrl_1, datasource_1, query_ctrl_1, aggregator_1, aggregator_editor_1, aggregators_1, group_by_tags_1, group_by_time_1, group_by_value_1, metric_name_field_1, tag_input_1, tags_select_1, timepicker_1, KairosDBQueryOptionsCtrl; var __moduleName = context_1 && context_1.id; return { setters: [ @@ -42,6 +42,9 @@ System.register(["angular", "./core/config_ctrl", "./core/datasource", "./core/q }, function (tags_select_1_1) { tags_select_1 = tags_select_1_1; + }, + function (timepicker_1_1) { + timepicker_1 = timepicker_1_1; } ], execute: function () { @@ -64,7 +67,8 @@ System.register(["angular", "./core/config_ctrl", "./core/datasource", "./core/q .directive("tagInput", tag_input_1.TagInputDirective) .directive("groupByValue", group_by_value_1.GroupByValueDirective) .directive("groupByTime", group_by_time_1.GroupByTimeDirective) - .directive("groupByTags", group_by_tags_1.GroupByTagsDirective); + .directive("groupByTags", group_by_tags_1.GroupByTagsDirective) + .directive("timePicker", timepicker_1.TimePickerDirective); } }; }); diff --git a/dist/module.js.map b/dist/module.js.map index 6d9a6513..387d1640 100644 --- a/dist/module.js.map +++ b/dist/module.js.map @@ -1 +1 @@ -{"version":3,"file":"module.js","sourceRoot":"","sources":["module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAIQ,gCAAkB;oCAClB,+BAAkB;mCAClB,8BAAiB;;gBAWzB;gBAEA,CAAC;gBADiB,oCAAW,GAAG,6BAA6B,CAAC;gBAC9D,+BAAC;aAAA,AAFD;;YAWA,iBAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC;iBAC/B,SAAS,CAAC,kBAAkB,EAAE,6CAAyB,CAAC;iBACxD,SAAS,CAAC,YAAY,EAAE,gCAAmB,CAAC;iBAC5C,SAAS,CAAC,aAAa,EAAE,kCAAoB,CAAC;iBAC9C,SAAS,CAAC,iBAAiB,EAAE,4CAAwB,CAAC;iBACtD,SAAS,CAAC,YAAY,EAAE,iCAAmB,CAAC;iBAC5C,SAAS,CAAC,UAAU,EAAE,6BAAiB,CAAC;iBACxC,SAAS,CAAC,cAAc,EAAE,sCAAqB,CAAC;iBAChD,SAAS,CAAC,aAAa,EAAE,oCAAoB,CAAC;iBAC9C,SAAS,CAAC,aAAa,EAAE,oCAAoB,CAAC,CAAC;QACpD,CAAC"} \ No newline at end of file +{"version":3,"file":"module.js","sourceRoot":"","sources":["module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAIQ,gCAAkB;oCAClB,+BAAkB;mCAClB,8BAAiB;;gBAYzB;gBAEA,CAAC;gBADiB,oCAAW,GAAG,6BAA6B,CAAC;gBAC9D,+BAAC;aAAA,AAFD;;YAWA,iBAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC;iBAC/B,SAAS,CAAC,kBAAkB,EAAE,6CAAyB,CAAC;iBACxD,SAAS,CAAC,YAAY,EAAE,gCAAmB,CAAC;iBAC5C,SAAS,CAAC,aAAa,EAAE,kCAAoB,CAAC;iBAC9C,SAAS,CAAC,iBAAiB,EAAE,4CAAwB,CAAC;iBACtD,SAAS,CAAC,YAAY,EAAE,iCAAmB,CAAC;iBAC5C,SAAS,CAAC,UAAU,EAAE,6BAAiB,CAAC;iBACxC,SAAS,CAAC,cAAc,EAAE,sCAAqB,CAAC;iBAChD,SAAS,CAAC,aAAa,EAAE,oCAAoB,CAAC;iBAC9C,SAAS,CAAC,aAAa,EAAE,oCAAoB,CAAC;iBAC9C,SAAS,CAAC,YAAY,EAAE,gCAAmB,CAAC,CAAC;QAClD,CAAC"} \ No newline at end of file diff --git a/dist/module.ts b/dist/module.ts index 19e6327e..07291fb5 100644 --- a/dist/module.ts +++ b/dist/module.ts @@ -14,6 +14,7 @@ import {GroupByValueDirective} from "./directives/group_by/group_by_value"; import {MetricNameFieldDirective} from "./directives/metric_name_field"; import {TagInputDirective} from "./directives/tag_input"; import {TagsSelectDirective} from "./directives/tags_select"; +import {TimePickerDirective} from "./directives/timepicker"; class KairosDBQueryOptionsCtrl { public static templateUrl = "partials/query.options.html"; @@ -35,4 +36,5 @@ angular.module("grafana.directives") .directive("tagInput", TagInputDirective) .directive("groupByValue", GroupByValueDirective) .directive("groupByTime", GroupByTimeDirective) - .directive("groupByTags", GroupByTagsDirective); + .directive("groupByTags", GroupByTagsDirective) + .directive("timePicker", TimePickerDirective); diff --git a/dist/package.json b/dist/package.json index 479ad2b1..6e8d11e4 100644 --- a/dist/package.json +++ b/dist/package.json @@ -11,7 +11,6 @@ "@types/chai": "^4.1.7", "@types/lodash": "^4.14.83", "@types/mocha": "^5.2.5", - "angular": "^1.6.6", "angular-mocks": "^1.6.6", "babel": "^6.23.0", "babel-plugin-transform-es2015-for-of": "^6.6.0", @@ -20,7 +19,7 @@ "brace": "^0.10.0", "chai": "^4.1.2", "es6-shim": "^0.35.3", - "grafana-sdk-mocks": "github:grafana/grafana-sdk-mocks", + "grafana-sdk-mocks": "github:briangann/grafana-sdk-mocks", "grunt": "^1.0.1", "grunt-babel": "~6.0.0", "grunt-contrib-clean": "^1.1.0", @@ -48,7 +47,6 @@ "lodash": "^4.17.4", "mocha": "^5.2.0", "mocha-each": "^1.1.0", - "moment": "^2.18.1", "plugin-typescript": "^7.1.1", "prunk": "~1.3.1", "q": "^1.5.1", @@ -60,7 +58,9 @@ "typescript": "^2.6.1" }, "dependencies": { - "grafana-sdk-mocks": "github:briangann/grafana-sdk-mocks" + "angular": "^1.6.6", + "grafana-sdk-mocks": "github:briangann/grafana-sdk-mocks", + "moment": "^2.22.2" }, "homepage": "https://github.com/grafana/kairosdb-datasource" } diff --git a/dist/partials/query.editor.html b/dist/partials/query.editor.html index e14ae6aa..d971b753 100644 --- a/dist/partials/query.editor.html +++ b/dist/partials/query.editor.html @@ -4,4 +4,5 @@ + diff --git a/dist/partials/time.override.editor.html b/dist/partials/time.override.editor.html new file mode 100644 index 00000000..d949b448 --- /dev/null +++ b/dist/partials/time.override.editor.html @@ -0,0 +1,20 @@ +
+
+
+ + + + +
+
+
diff --git a/dist/partials/timepicker.html b/dist/partials/timepicker.html new file mode 100644 index 00000000..abbd6590 --- /dev/null +++ b/dist/partials/timepicker.html @@ -0,0 +1,56 @@ +
+ +
+ +
+
+

Custom range

+ + +
+
+ +
+
+ +
+
+ +
+ +
+ + + +
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+

Quick ranges

+
    +
  • + +
  • +
+
+
+ diff --git a/dist/utils/moment.shim.d.ts b/dist/utils/moment.shim.d.ts new file mode 100644 index 00000000..a95c6518 --- /dev/null +++ b/dist/utils/moment.shim.d.ts @@ -0,0 +1,8 @@ + +import * as moment from "moment"; + +declare module "moment" { + export type Moment = any; +} + +export = moment; diff --git a/dist/utils/rangeutil.d.ts b/dist/utils/rangeutil.d.ts new file mode 100644 index 00000000..e090d22f --- /dev/null +++ b/dist/utils/rangeutil.d.ts @@ -0,0 +1,8 @@ +import { Moment } from "moment"; +export interface RawTimeRange { + from: any; + to: Moment | string; +} +export declare function getRelativeTimesList(timepickerSettings: any, currentDisplay: any): any; +export declare function describeTextRange(expr: any): any; +export declare function describeTimeRange(range: RawTimeRange): string; diff --git a/dist/utils/rangeutil.js b/dist/utils/rangeutil.js new file mode 100644 index 00000000..31c9a15d --- /dev/null +++ b/dist/utils/rangeutil.js @@ -0,0 +1,147 @@ +System.register(["app/core/utils/datemath", "lodash", "moment"], function (exports_1, context_1) { + "use strict"; + var dateMath, lodash_1, moment_1, spans, rangeOptions, absoluteFormat, rangeIndex; + var __moduleName = context_1 && context_1.id; + function getRelativeTimesList(timepickerSettings, currentDisplay) { + var groups = lodash_1.default.groupBy(rangeOptions, function (option) { + option.active = option.display === currentDisplay; + return option.section; + }); + return groups; + } + exports_1("getRelativeTimesList", getRelativeTimesList); + function formatDate(date) { + return date.format(absoluteFormat); + } + function describeTextRange(expr) { + var isLast = expr.indexOf("+") !== 0; + if (expr.indexOf("now") === -1) { + expr = (isLast ? "now-" : "now") + expr; + } + var opt = rangeIndex[expr + " to now"]; + if (opt) { + return opt; + } + if (isLast) { + opt = { from: expr, to: "now" }; + } + else { + opt = { from: "now", to: expr }; + } + var parts = /^now([-+])(\d+)(\w)/.exec(expr); + if (parts) { + var unit = parts[3]; + var amount = parseInt(parts[2], 10); + var span = spans[unit]; + if (span) { + opt.display = isLast ? "Last " : "Next "; + opt.display += amount + " " + span.display; + opt.section = span.section; + if (amount > 1) { + opt.display += "s"; + } + } + } + else { + opt.display = opt.from + " to " + opt.to; + opt.invalid = true; + } + return opt; + } + exports_1("describeTextRange", describeTextRange); + function describeTimeRange(range) { + var option = rangeIndex[range.from.toString() + " to " + range.to.toString()]; + if (option) { + return option.display; + } + if (moment_1.default.isMoment(range.from) && moment_1.default.isMoment(range.to)) { + return formatDate(range.from) + " to " + formatDate(range.to); + } + if (moment_1.default.isMoment(range.from)) { + var toMoment = dateMath.parse(range.to, true); + return formatDate(range.from) + " to " + toMoment.fromNow(); + } + if (moment_1.default.isMoment(range.to)) { + var from = dateMath.parse(range.from, false); + return from.fromNow() + " to " + formatDate(range.to); + } + if (range.to.toString() === "now") { + var res = describeTextRange(range.from); + return res.display; + } + return range.from.toString() + " to " + range.to.toString(); + } + exports_1("describeTimeRange", describeTimeRange); + return { + setters: [ + function (dateMath_1) { + dateMath = dateMath_1; + }, + function (lodash_1_1) { + lodash_1 = lodash_1_1; + }, + function (moment_1_1) { + moment_1 = moment_1_1; + } + ], + execute: function () { + spans = { + s: { display: "second" }, + m: { display: "minute" }, + h: { display: "hour" }, + d: { display: "day" }, + w: { display: "week" }, + M: { display: "month" }, + y: { display: "year" }, + }; + rangeOptions = [ + { from: "now/d", to: "now/d", display: "Today", section: 2 }, + { from: "now/d", to: "now", display: "Today so far", section: 2 }, + { from: "now/w", to: "now/w", display: "This week", section: 2 }, + { from: "now/w", to: "now", display: "This week so far", section: 2 }, + { from: "now/M", to: "now/M", display: "This month", section: 2 }, + { from: "now/M", to: "now", display: "This month so far", section: 2 }, + { from: "now/y", to: "now/y", display: "This year", section: 2 }, + { from: "now/y", to: "now", display: "This year so far", section: 2 }, + { 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: 3 }, + { from: "now-15m", to: "now", display: "Last 15 minutes", section: 3 }, + { from: "now-30m", to: "now", display: "Last 30 minutes", section: 3 }, + { from: "now-1h", to: "now", display: "Last 1 hour", section: 3 }, + { from: "now-3h", to: "now", display: "Last 3 hours", section: 3 }, + { from: "now-6h", to: "now", display: "Last 6 hours", section: 3 }, + { from: "now-12h", to: "now", display: "Last 12 hours", section: 3 }, + { from: "now-24h", to: "now", display: "Last 24 hours", section: 3 }, + { from: "now-2d", to: "now", display: "Last 2 days", section: 0 }, + { from: "now-7d", to: "now", display: "Last 7 days", section: 0 }, + { from: "now-30d", to: "now", display: "Last 30 days", section: 0 }, + { from: "now-90d", to: "now", display: "Last 90 days", section: 0 }, + { from: "now-6M", to: "now", display: "Last 6 months", section: 0 }, + { from: "now-1y", to: "now", display: "Last 1 year", section: 0 }, + { from: "now-2y", to: "now", display: "Last 2 years", section: 0 }, + { from: "now-5y", to: "now", display: "Last 5 years", section: 0 }, + ]; + absoluteFormat = "MMM D, YYYY HH:mm:ss"; + rangeIndex = {}; + lodash_1.default.each(rangeOptions, function (frame) { + rangeIndex[frame.from + " to " + frame.to] = frame; + }); + } + }; +}); +//# sourceMappingURL=rangeutil.js.map \ No newline at end of file diff --git a/dist/utils/rangeutil.js.map b/dist/utils/rangeutil.js.map new file mode 100644 index 00000000..07f7ef9c --- /dev/null +++ b/dist/utils/rangeutil.js.map @@ -0,0 +1 @@ +{"version":3,"file":"rangeutil.js","sourceRoot":"","sources":["rangeutil.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/utils/rangeutil.ts b/dist/utils/rangeutil.ts new file mode 100644 index 00000000..cb81d7a8 --- /dev/null +++ b/dist/utils/rangeutil.ts @@ -0,0 +1,163 @@ +import * as dateMath from "app/core/utils/datemath"; +import _ from "lodash"; +import moment, {Moment} from "moment"; + +export interface RawTimeRange { + from: any; + to: Moment | string; +} + +const spans = { + s: { display: "second" }, + m: { display: "minute" }, + h: { display: "hour" }, + d: { display: "day" }, + w: { display: "week" }, + M: { display: "month" }, + y: { display: "year" }, +}; + +const rangeOptions = [ + { from: "now/d", to: "now/d", display: "Today", section: 2 }, + { from: "now/d", to: "now", display: "Today so far", section: 2 }, + { from: "now/w", to: "now/w", display: "This week", section: 2 }, + { from: "now/w", to: "now", display: "This week so far", section: 2 }, + { from: "now/M", to: "now/M", display: "This month", section: 2 }, + { from: "now/M", to: "now", display: "This month so far", section: 2 }, + { from: "now/y", to: "now/y", display: "This year", section: 2 }, + { from: "now/y", to: "now", display: "This year so far", section: 2 }, + + { 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: 3 }, + { from: "now-15m", to: "now", display: "Last 15 minutes", section: 3 }, + { from: "now-30m", to: "now", display: "Last 30 minutes", section: 3 }, + { from: "now-1h", to: "now", display: "Last 1 hour", section: 3 }, + { from: "now-3h", to: "now", display: "Last 3 hours", section: 3 }, + { from: "now-6h", to: "now", display: "Last 6 hours", section: 3 }, + { from: "now-12h", to: "now", display: "Last 12 hours", section: 3 }, + { from: "now-24h", to: "now", display: "Last 24 hours", section: 3 }, + + { from: "now-2d", to: "now", display: "Last 2 days", section: 0 }, + { from: "now-7d", to: "now", display: "Last 7 days", section: 0 }, + { from: "now-30d", to: "now", display: "Last 30 days", section: 0 }, + { from: "now-90d", to: "now", display: "Last 90 days", section: 0 }, + { from: "now-6M", to: "now", display: "Last 6 months", section: 0 }, + { from: "now-1y", to: "now", display: "Last 1 year", section: 0 }, + { from: "now-2y", to: "now", display: "Last 2 years", section: 0 }, + { from: "now-5y", to: "now", display: "Last 5 years", section: 0 }, +]; + +const absoluteFormat = "MMM D, YYYY HH:mm:ss"; + +const rangeIndex = {}; +_.each(rangeOptions, (frame) => { + rangeIndex[frame.from + " to " + frame.to] = frame; +}); + +export function getRelativeTimesList(timepickerSettings, currentDisplay) { + const groups = _.groupBy(rangeOptions, (option: any) => { + option.active = option.display === currentDisplay; + return option.section; + }); + + // _.each(timepickerSettings.time_options, (duration: string) => { + // let info = describeTextRange(duration); + // if (info.section) { + // groups[info.section].push(info); + // } + // }); + + return groups; +} + +function formatDate(date) { + return date.format(absoluteFormat); +} + +// handles expressions like +// 5m +// 5m to now/d +// now/d to now +// now/d +// if no to then to now is assumed +export function describeTextRange(expr: any) { + const isLast = expr.indexOf("+") !== 0; + if (expr.indexOf("now") === -1) { + expr = (isLast ? "now-" : "now") + expr; + } + + let opt = rangeIndex[expr + " to now"]; + if (opt) { + return opt; + } + + if (isLast) { + opt = { from: expr, to: "now" }; + } else { + opt = { from: "now", to: expr }; + } + + const parts = /^now([-+])(\d+)(\w)/.exec(expr); + if (parts) { + const unit = parts[3]; + const amount = parseInt(parts[2], 10); + const span = spans[unit]; + if (span) { + opt.display = isLast ? "Last " : "Next "; + opt.display += amount + " " + span.display; + opt.section = span.section; + if (amount > 1) { + opt.display += "s"; + } + } + } else { + opt.display = opt.from + " to " + opt.to; + opt.invalid = true; + } + + return opt; +} + +export function describeTimeRange(range: RawTimeRange): string { + const option = rangeIndex[range.from.toString() + " to " + range.to.toString()]; + if (option) { + return option.display; + } + + if (moment.isMoment(range.from) && moment.isMoment(range.to)) { + return formatDate(range.from) + " to " + formatDate(range.to); + } + + if (moment.isMoment(range.from)) { + const toMoment = dateMath.parse(range.to, true); + return formatDate(range.from) + " to " + toMoment.fromNow(); + } + + if (moment.isMoment(range.to)) { + const from = dateMath.parse(range.from, false); + return from.fromNow() + " to " + formatDate(range.to); + } + + if (range.to.toString() === "now") { + const res = describeTextRange(range.from); + return res.display; + } + + return range.from.toString() + " to " + range.to.toString(); +} diff --git a/package.json b/package.json index 479ad2b1..6e8d11e4 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "@types/chai": "^4.1.7", "@types/lodash": "^4.14.83", "@types/mocha": "^5.2.5", - "angular": "^1.6.6", "angular-mocks": "^1.6.6", "babel": "^6.23.0", "babel-plugin-transform-es2015-for-of": "^6.6.0", @@ -20,7 +19,7 @@ "brace": "^0.10.0", "chai": "^4.1.2", "es6-shim": "^0.35.3", - "grafana-sdk-mocks": "github:grafana/grafana-sdk-mocks", + "grafana-sdk-mocks": "github:briangann/grafana-sdk-mocks", "grunt": "^1.0.1", "grunt-babel": "~6.0.0", "grunt-contrib-clean": "^1.1.0", @@ -48,7 +47,6 @@ "lodash": "^4.17.4", "mocha": "^5.2.0", "mocha-each": "^1.1.0", - "moment": "^2.18.1", "plugin-typescript": "^7.1.1", "prunk": "~1.3.1", "q": "^1.5.1", @@ -60,7 +58,9 @@ "typescript": "^2.6.1" }, "dependencies": { - "grafana-sdk-mocks": "github:briangann/grafana-sdk-mocks" + "angular": "^1.6.6", + "grafana-sdk-mocks": "github:briangann/grafana-sdk-mocks", + "moment": "^2.22.2" }, "homepage": "https://github.com/grafana/kairosdb-datasource" } diff --git a/src/beans/request/metric_query.ts b/src/beans/request/metric_query.ts index 91e05121..38abe7a9 100644 --- a/src/beans/request/metric_query.ts +++ b/src/beans/request/metric_query.ts @@ -4,11 +4,15 @@ export class MetricQuery { public limit: number = 0; public aggregators: any[]; public group_by: any[]; + public start_absolute: number; + public end_absolute: number; - constructor(name: string, tags: any, aggregators: any[], group_by: any[]) { + constructor(name: string, tags: any, aggregators: any[], group_by: any[], start_absolute: number, end_absolute: number) { this.name = name; this.tags = tags; this.aggregators = aggregators; this.group_by = group_by; + this.start_absolute = start_absolute; + this.end_absolute = end_absolute; } } diff --git a/src/beans/request/target.ts b/src/beans/request/target.ts index 6a420087..3cedc612 100644 --- a/src/beans/request/target.ts +++ b/src/beans/request/target.ts @@ -1,8 +1,15 @@ +import * as dateMath from "app/core/utils/datemath"; +import {Moment} from "moment"; import {Aggregator} from "../aggregators/aggregator"; import * as Aggregators from "../aggregators/aggregators"; import {AggregatorParameter} from "../aggregators/parameters/aggregator_parameter"; import {GroupBy} from "./group_by"; +export interface TimeRange { + from: Moment | string; + to: Moment | string; +} + export class KairosDBTarget { public static fromObject(object: any): KairosDBTarget { const rval = new KairosDBTarget(); @@ -12,14 +19,36 @@ export class KairosDBTarget { rval.groupBy = GroupBy.fromObject(object.groupBy); rval.aggregators = (object.aggregators || []).map( (val) => Aggregators.fromObject(val)); + rval.timeRange = object.timeRange; return rval; } + public static startTime(target: KairosDBTarget): number { + if (target.timeRange) { + const startMoment: Moment = dateMath.parse(target.timeRange.from); + if (startMoment) { + return startMoment.unix() * 1000; + } + } + return undefined; + } + + public static endTime(target: KairosDBTarget): number { + if (target.timeRange) { + const endMoment: Moment = dateMath.parse(target.timeRange.to); + if (endMoment) { + return endMoment.unix() * 1000; + } + } + return undefined; + } + public metricName: string = undefined; public alias: string = undefined; public tags: {[key: string]: string[]} = {}; public groupBy: GroupBy = new GroupBy(); public aggregators: Aggregator[] = []; + public timeRange: TimeRange = undefined; public asString(): string { let str = "SELECT "; diff --git a/src/core/request/query_builder.ts b/src/core/request/query_builder.ts index f61cbdc1..253c2af3 100644 --- a/src/core/request/query_builder.ts +++ b/src/core/request/query_builder.ts @@ -63,7 +63,9 @@ export class KairosDBQueryBuilder { target.metricName, this.unpackTags(_.pickBy(target.tags, (tagValues) => tagValues.length)), target.aggregators.map((aggregator) => this.convertAggregatorToQueryObject(aggregator, defaultInterval)), - this.groupBysBuilder.build(target.groupBy) + this.groupBysBuilder.build(target.groupBy), + KairosDBTarget.startTime(target), + KairosDBTarget.endTime(target) ); } diff --git a/src/directives/timepicker.ts b/src/directives/timepicker.ts new file mode 100644 index 00000000..98253a01 --- /dev/null +++ b/src/directives/timepicker.ts @@ -0,0 +1,162 @@ +import angular from "angular"; +import * as dateMath from "app/core/utils/datemath"; +import _ from "lodash"; +import moment from "moment"; + +import {KairosDBTarget} from "../beans/request/target"; +import * as rangeUtil from "../utils/rangeutil"; + +export class TimePickerCtrl { + public static tooltipFormat = "MMM D, YYYY HH:mm:ss"; + public static defaults = { + time_options: ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"], + refresh_intervals: ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], + }; + + public dashboard: any; + public query: KairosDBTarget; + public panel: any; + public absolute: any; + public timeRaw: any; + public editTimeRaw: any; + public tooltip: string; + public rangeString: string; + public timeOptions: any; + public refresh: any; + public isUtc: boolean; + public firstDayOfWeek: number; + public isOpen: boolean; + public isAbsolute: boolean; + + /** @ngInject */ + constructor(private $scope, private $rootScope, private timeSrv) { + this.$scope.ctrl = this; + + $scope.$parent.$watch("timeOverridden", (newValue, oldValue) => { + if (newValue !== undefined) { + if (newValue) { + this.enableOverride(); + } else { + this.disableOverride(); + } + } + }); + + $rootScope.onAppEvent("closeTimepicker", this.openDropdown.bind(this), $scope); + + this.dashboard.on("refresh", this.onRefresh.bind(this), $scope); + + // init options + this.panel = this.dashboard.timepicker; + _.defaults(this.panel, TimePickerCtrl.defaults); + this.firstDayOfWeek = moment.localeData().firstDayOfWeek(); + + // init time stuff + this.onRefresh(); + } + + public onRefresh() { + let timeRaw = angular.copy(this.query.timeRange); + + if (!timeRaw) { + timeRaw = this.timeSrv.timeRange().raw; + } + + if (!this.dashboard.isTimezoneUtc()) { + if (moment.isMoment(timeRaw.from)) { + timeRaw.from.local(); + } + if (moment.isMoment(timeRaw.to)) { + timeRaw.to.local(); + } + this.isUtc = false; + } else { + this.isUtc = true; + } + + const fromMoment = dateMath.parse(timeRaw.from); + const toMoment = dateMath.parse(timeRaw.to); + + this.rangeString = rangeUtil.describeTimeRange(timeRaw); + this.absolute = { fromJs: fromMoment.toDate(), toJs: toMoment.toDate() }; + this.tooltip = this.dashboard.formatDate(fromMoment) + "
to
"; + this.tooltip += this.dashboard.formatDate(toMoment); + this.timeRaw = timeRaw; + this.isAbsolute = moment.isMoment(this.timeRaw.to); + } + + public openDropdown() { + if (this.isOpen) { + this.closeDropdown(); + return; + } + + this.onRefresh(); + this.editTimeRaw = this.timeRaw; + this.timeOptions = rangeUtil.getRelativeTimesList(this.panel, this.rangeString); + this.refresh = { + value: this.dashboard.refresh, + options: _.map(this.panel.refresh_intervals, (interval: any) => { + return { text: interval, value: interval }; + }), + }; + + this.refresh.options.unshift({ text: "off" }); + this.isOpen = true; + this.$rootScope.appEvent("timepickerOpen"); + } + + public closeDropdown() { + this.isOpen = false; + this.onRefresh(); + this.$rootScope.appEvent("timepickerClosed"); + } + + public absoluteFromChanged() { + this.editTimeRaw.from = this.getAbsoluteMomentForTimezone(this.absolute.fromJs); + } + + public absoluteToChanged() { + this.editTimeRaw.to = this.getAbsoluteMomentForTimezone(this.absolute.toJs); + } + + public getAbsoluteMomentForTimezone(jsDate) { + return this.dashboard.isTimezoneUtc() ? moment(jsDate).utc() : moment(jsDate); + } + + public setRelativeFilter(timespan) { + const range = { from: timespan.from, to: timespan.to }; + + if (this.panel.nowDelay && range.to === "now") { + range.to = "now-" + this.panel.nowDelay; + } + + this.query.timeRange = range; + this.closeDropdown(); + } + + public enableOverride() { + const timeRaw = this.timeSrv.timeRange().raw; + this.query.timeRange = {from: timeRaw.from, to: timeRaw.to}; + this.onRefresh(); + } + + public disableOverride() { + this.query.timeRange = undefined; + this.onRefresh(); + } +} + +export function TimePickerDirective() { + return { + restrict: "E", + templateUrl: "public/plugins/grafana-kairosdb-datasource/partials/timepicker.html", + controller: TimePickerCtrl, + bindToController: true, + controllerAs: "ctrl", + scope: { + dashboard: "=", + query: "=", + }, + }; +} diff --git a/src/module.ts b/src/module.ts index 19e6327e..07291fb5 100644 --- a/src/module.ts +++ b/src/module.ts @@ -14,6 +14,7 @@ import {GroupByValueDirective} from "./directives/group_by/group_by_value"; import {MetricNameFieldDirective} from "./directives/metric_name_field"; import {TagInputDirective} from "./directives/tag_input"; import {TagsSelectDirective} from "./directives/tags_select"; +import {TimePickerDirective} from "./directives/timepicker"; class KairosDBQueryOptionsCtrl { public static templateUrl = "partials/query.options.html"; @@ -35,4 +36,5 @@ angular.module("grafana.directives") .directive("tagInput", TagInputDirective) .directive("groupByValue", GroupByValueDirective) .directive("groupByTime", GroupByTimeDirective) - .directive("groupByTags", GroupByTagsDirective); + .directive("groupByTags", GroupByTagsDirective) + .directive("timePicker", TimePickerDirective); diff --git a/src/partials/query.editor.html b/src/partials/query.editor.html index e14ae6aa..d971b753 100644 --- a/src/partials/query.editor.html +++ b/src/partials/query.editor.html @@ -4,4 +4,5 @@ + diff --git a/src/partials/time.override.editor.html b/src/partials/time.override.editor.html new file mode 100644 index 00000000..d949b448 --- /dev/null +++ b/src/partials/time.override.editor.html @@ -0,0 +1,20 @@ +
+
+
+ + + + +
+
+
diff --git a/src/partials/timepicker.html b/src/partials/timepicker.html new file mode 100644 index 00000000..abbd6590 --- /dev/null +++ b/src/partials/timepicker.html @@ -0,0 +1,56 @@ +
+ +
+ +
+
+

Custom range

+ + +
+
+ +
+
+ +
+
+ +
+ +
+ + + +
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+

Quick ranges

+
    +
  • + +
  • +
+
+
+ diff --git a/src/utils/moment.shim.d.ts b/src/utils/moment.shim.d.ts new file mode 100644 index 00000000..a95c6518 --- /dev/null +++ b/src/utils/moment.shim.d.ts @@ -0,0 +1,8 @@ + +import * as moment from "moment"; + +declare module "moment" { + export type Moment = any; +} + +export = moment; diff --git a/src/utils/rangeutil.ts b/src/utils/rangeutil.ts new file mode 100644 index 00000000..cb81d7a8 --- /dev/null +++ b/src/utils/rangeutil.ts @@ -0,0 +1,163 @@ +import * as dateMath from "app/core/utils/datemath"; +import _ from "lodash"; +import moment, {Moment} from "moment"; + +export interface RawTimeRange { + from: any; + to: Moment | string; +} + +const spans = { + s: { display: "second" }, + m: { display: "minute" }, + h: { display: "hour" }, + d: { display: "day" }, + w: { display: "week" }, + M: { display: "month" }, + y: { display: "year" }, +}; + +const rangeOptions = [ + { from: "now/d", to: "now/d", display: "Today", section: 2 }, + { from: "now/d", to: "now", display: "Today so far", section: 2 }, + { from: "now/w", to: "now/w", display: "This week", section: 2 }, + { from: "now/w", to: "now", display: "This week so far", section: 2 }, + { from: "now/M", to: "now/M", display: "This month", section: 2 }, + { from: "now/M", to: "now", display: "This month so far", section: 2 }, + { from: "now/y", to: "now/y", display: "This year", section: 2 }, + { from: "now/y", to: "now", display: "This year so far", section: 2 }, + + { 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: 3 }, + { from: "now-15m", to: "now", display: "Last 15 minutes", section: 3 }, + { from: "now-30m", to: "now", display: "Last 30 minutes", section: 3 }, + { from: "now-1h", to: "now", display: "Last 1 hour", section: 3 }, + { from: "now-3h", to: "now", display: "Last 3 hours", section: 3 }, + { from: "now-6h", to: "now", display: "Last 6 hours", section: 3 }, + { from: "now-12h", to: "now", display: "Last 12 hours", section: 3 }, + { from: "now-24h", to: "now", display: "Last 24 hours", section: 3 }, + + { from: "now-2d", to: "now", display: "Last 2 days", section: 0 }, + { from: "now-7d", to: "now", display: "Last 7 days", section: 0 }, + { from: "now-30d", to: "now", display: "Last 30 days", section: 0 }, + { from: "now-90d", to: "now", display: "Last 90 days", section: 0 }, + { from: "now-6M", to: "now", display: "Last 6 months", section: 0 }, + { from: "now-1y", to: "now", display: "Last 1 year", section: 0 }, + { from: "now-2y", to: "now", display: "Last 2 years", section: 0 }, + { from: "now-5y", to: "now", display: "Last 5 years", section: 0 }, +]; + +const absoluteFormat = "MMM D, YYYY HH:mm:ss"; + +const rangeIndex = {}; +_.each(rangeOptions, (frame) => { + rangeIndex[frame.from + " to " + frame.to] = frame; +}); + +export function getRelativeTimesList(timepickerSettings, currentDisplay) { + const groups = _.groupBy(rangeOptions, (option: any) => { + option.active = option.display === currentDisplay; + return option.section; + }); + + // _.each(timepickerSettings.time_options, (duration: string) => { + // let info = describeTextRange(duration); + // if (info.section) { + // groups[info.section].push(info); + // } + // }); + + return groups; +} + +function formatDate(date) { + return date.format(absoluteFormat); +} + +// handles expressions like +// 5m +// 5m to now/d +// now/d to now +// now/d +// if no to then to now is assumed +export function describeTextRange(expr: any) { + const isLast = expr.indexOf("+") !== 0; + if (expr.indexOf("now") === -1) { + expr = (isLast ? "now-" : "now") + expr; + } + + let opt = rangeIndex[expr + " to now"]; + if (opt) { + return opt; + } + + if (isLast) { + opt = { from: expr, to: "now" }; + } else { + opt = { from: "now", to: expr }; + } + + const parts = /^now([-+])(\d+)(\w)/.exec(expr); + if (parts) { + const unit = parts[3]; + const amount = parseInt(parts[2], 10); + const span = spans[unit]; + if (span) { + opt.display = isLast ? "Last " : "Next "; + opt.display += amount + " " + span.display; + opt.section = span.section; + if (amount > 1) { + opt.display += "s"; + } + } + } else { + opt.display = opt.from + " to " + opt.to; + opt.invalid = true; + } + + return opt; +} + +export function describeTimeRange(range: RawTimeRange): string { + const option = rangeIndex[range.from.toString() + " to " + range.to.toString()]; + if (option) { + return option.display; + } + + if (moment.isMoment(range.from) && moment.isMoment(range.to)) { + return formatDate(range.from) + " to " + formatDate(range.to); + } + + if (moment.isMoment(range.from)) { + const toMoment = dateMath.parse(range.to, true); + return formatDate(range.from) + " to " + toMoment.fromNow(); + } + + if (moment.isMoment(range.to)) { + const from = dateMath.parse(range.from, false); + return from.fromNow() + " to " + formatDate(range.to); + } + + if (range.to.toString() === "now") { + const res = describeTextRange(range.from); + return res.display; + } + + return range.from.toString() + " to " + range.to.toString(); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..24b1ccd9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "es5", + "outDir": "./dist", + "module": "system", + "moduleResolution": "node" + } +} \ No newline at end of file