mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
singlestat: render time of last point based on dashboard timezone (#11425)
* singlestat: render time of last point based on dashboard timezone * changelog: add note for #10338
This commit is contained in:
parent
e52aceeaba
commit
ef0b7bda6f
@ -56,6 +56,7 @@
|
|||||||
* **Cloudwatch**: Add dimension filtering to CloudWatch `dimension_values()` [#10029](https://github.com/grafana/grafana/issues/10029), thx [@willyhutw](https://github.com/willyhutw)
|
* **Cloudwatch**: Add dimension filtering to CloudWatch `dimension_values()` [#10029](https://github.com/grafana/grafana/issues/10029), thx [@willyhutw](https://github.com/willyhutw)
|
||||||
* **Units**: Second to HH:mm:ss formatter [#11107](https://github.com/grafana/grafana/issues/11107), thx [@gladdiologist](https://github.com/gladdiologist)
|
* **Units**: Second to HH:mm:ss formatter [#11107](https://github.com/grafana/grafana/issues/11107), thx [@gladdiologist](https://github.com/gladdiologist)
|
||||||
* **Singlestat**: Add color to prefix and postfix in singlestat panel [#11143](https://github.com/grafana/grafana/pull/11143), thx [@ApsOps](https://github.com/ApsOps)
|
* **Singlestat**: Add color to prefix and postfix in singlestat panel [#11143](https://github.com/grafana/grafana/pull/11143), thx [@ApsOps](https://github.com/ApsOps)
|
||||||
|
* **Singlestat**: Fix "time of last point" shows local time when dashboard timezone set to UTC [#10338](https://github.com/grafana/grafana/issues/10338)
|
||||||
* **Dashboards**: Version cleanup fails on old databases with many entries [#11278](https://github.com/grafana/grafana/issues/11278)
|
* **Dashboards**: Version cleanup fails on old databases with many entries [#11278](https://github.com/grafana/grafana/issues/11278)
|
||||||
* **Server**: Adjust permissions of unix socket [#11343](https://github.com/grafana/grafana/pull/11343), thx [@corny](https://github.com/corny)
|
* **Server**: Adjust permissions of unix socket [#11343](https://github.com/grafana/grafana/pull/11343), thx [@corny](https://github.com/corny)
|
||||||
* **Shortcuts**: Add shortcut for duplicate panel [#11102](https://github.com/grafana/grafana/issues/11102)
|
* **Shortcuts**: Add shortcut for duplicate panel [#11102](https://github.com/grafana/grafana/issues/11102)
|
||||||
|
@ -101,38 +101,88 @@ describeValueFormat('d', 245, 100, 0, '35 week');
|
|||||||
describeValueFormat('d', 2456, 10, 0, '6.73 year');
|
describeValueFormat('d', 2456, 10, 0, '6.73 year');
|
||||||
|
|
||||||
describe('date time formats', function() {
|
describe('date time formats', function() {
|
||||||
|
const epoch = 1505634997920;
|
||||||
|
const utcTime = moment.utc(epoch);
|
||||||
|
const browserTime = moment(epoch);
|
||||||
|
|
||||||
it('should format as iso date', function() {
|
it('should format as iso date', function() {
|
||||||
var str = kbn.valueFormats.dateTimeAsIso(1505634997920, 1);
|
var expected = browserTime.format('YYYY-MM-DD HH:mm:ss');
|
||||||
expect(str).toBe(moment(1505634997920).format('YYYY-MM-DD HH:mm:ss'));
|
var actual = kbn.valueFormats.dateTimeAsIso(epoch);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format as iso date (in UTC)', function() {
|
||||||
|
var expected = utcTime.format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
var actual = kbn.valueFormats.dateTimeAsIso(epoch, true);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should format as iso date and skip date when today', function() {
|
it('should format as iso date and skip date when today', function() {
|
||||||
var now = moment();
|
var now = moment();
|
||||||
var str = kbn.valueFormats.dateTimeAsIso(now.valueOf(), 1);
|
var expected = now.format('HH:mm:ss');
|
||||||
expect(str).toBe(now.format('HH:mm:ss'));
|
var actual = kbn.valueFormats.dateTimeAsIso(now.valueOf(), false);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format as iso date (in UTC) and skip date when today', function() {
|
||||||
|
var now = moment.utc();
|
||||||
|
var expected = now.format('HH:mm:ss');
|
||||||
|
var actual = kbn.valueFormats.dateTimeAsIso(now.valueOf(), true);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should format as US date', function() {
|
it('should format as US date', function() {
|
||||||
var str = kbn.valueFormats.dateTimeAsUS(1505634997920, 1);
|
var expected = browserTime.format('MM/DD/YYYY h:mm:ss a');
|
||||||
expect(str).toBe(moment(1505634997920).format('MM/DD/YYYY h:mm:ss a'));
|
var actual = kbn.valueFormats.dateTimeAsUS(epoch, false);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format as US date (in UTC)', function() {
|
||||||
|
var expected = utcTime.format('MM/DD/YYYY h:mm:ss a');
|
||||||
|
var actual = kbn.valueFormats.dateTimeAsUS(epoch, true);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should format as US date and skip date when today', function() {
|
it('should format as US date and skip date when today', function() {
|
||||||
var now = moment();
|
var now = moment();
|
||||||
var str = kbn.valueFormats.dateTimeAsUS(now.valueOf(), 1);
|
var expected = now.format('h:mm:ss a');
|
||||||
expect(str).toBe(now.format('h:mm:ss a'));
|
var actual = kbn.valueFormats.dateTimeAsUS(now.valueOf(), false);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format as US date (in UTC) and skip date when today', function() {
|
||||||
|
var now = moment.utc();
|
||||||
|
var expected = now.format('h:mm:ss a');
|
||||||
|
var actual = kbn.valueFormats.dateTimeAsUS(now.valueOf(), true);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should format as from now with days', function() {
|
it('should format as from now with days', function() {
|
||||||
var daysAgo = moment().add(-7, 'd');
|
var daysAgo = moment().add(-7, 'd');
|
||||||
var str = kbn.valueFormats.dateTimeFromNow(daysAgo.valueOf(), 1);
|
var expected = '7 days ago';
|
||||||
expect(str).toBe('7 days ago');
|
var actual = kbn.valueFormats.dateTimeFromNow(daysAgo.valueOf(), false);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format as from now with days (in UTC)', function() {
|
||||||
|
var daysAgo = moment.utc().add(-7, 'd');
|
||||||
|
var expected = '7 days ago';
|
||||||
|
var actual = kbn.valueFormats.dateTimeFromNow(daysAgo.valueOf(), true);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should format as from now with minutes', function() {
|
it('should format as from now with minutes', function() {
|
||||||
var daysAgo = moment().add(-2, 'm');
|
var daysAgo = moment().add(-2, 'm');
|
||||||
var str = kbn.valueFormats.dateTimeFromNow(daysAgo.valueOf(), 1);
|
var expected = '2 minutes ago';
|
||||||
expect(str).toBe('2 minutes ago');
|
var actual = kbn.valueFormats.dateTimeFromNow(daysAgo.valueOf(), false);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format as from now with minutes (in UTC)', function() {
|
||||||
|
var daysAgo = moment.utc().add(-2, 'm');
|
||||||
|
var expected = '2 minutes ago';
|
||||||
|
var actual = kbn.valueFormats.dateTimeFromNow(daysAgo.valueOf(), true);
|
||||||
|
expect(actual).toBe(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -816,8 +816,8 @@ kbn.valueFormats.timeticks = function(size, decimals, scaledDecimals) {
|
|||||||
return kbn.valueFormats.s(size / 100, decimals, scaledDecimals);
|
return kbn.valueFormats.s(size / 100, decimals, scaledDecimals);
|
||||||
};
|
};
|
||||||
|
|
||||||
kbn.valueFormats.dateTimeAsIso = function(epoch) {
|
kbn.valueFormats.dateTimeAsIso = function(epoch, isUtc) {
|
||||||
var time = moment(epoch);
|
var time = isUtc ? moment.utc(epoch) : moment(epoch);
|
||||||
|
|
||||||
if (moment().isSame(epoch, 'day')) {
|
if (moment().isSame(epoch, 'day')) {
|
||||||
return time.format('HH:mm:ss');
|
return time.format('HH:mm:ss');
|
||||||
@ -825,8 +825,8 @@ kbn.valueFormats.dateTimeAsIso = function(epoch) {
|
|||||||
return time.format('YYYY-MM-DD HH:mm:ss');
|
return time.format('YYYY-MM-DD HH:mm:ss');
|
||||||
};
|
};
|
||||||
|
|
||||||
kbn.valueFormats.dateTimeAsUS = function(epoch) {
|
kbn.valueFormats.dateTimeAsUS = function(epoch, isUtc) {
|
||||||
var time = moment(epoch);
|
var time = isUtc ? moment.utc(epoch) : moment(epoch);
|
||||||
|
|
||||||
if (moment().isSame(epoch, 'day')) {
|
if (moment().isSame(epoch, 'day')) {
|
||||||
return time.format('h:mm:ss a');
|
return time.format('h:mm:ss a');
|
||||||
@ -834,8 +834,9 @@ kbn.valueFormats.dateTimeAsUS = function(epoch) {
|
|||||||
return time.format('MM/DD/YYYY h:mm:ss a');
|
return time.format('MM/DD/YYYY h:mm:ss a');
|
||||||
};
|
};
|
||||||
|
|
||||||
kbn.valueFormats.dateTimeFromNow = function(epoch) {
|
kbn.valueFormats.dateTimeFromNow = function(epoch, isUtc) {
|
||||||
return moment(epoch).fromNow();
|
var time = isUtc ? moment.utc(epoch) : moment(epoch);
|
||||||
|
return time.fromNow();
|
||||||
};
|
};
|
||||||
|
|
||||||
///// FORMAT MENU /////
|
///// FORMAT MENU /////
|
||||||
|
@ -308,7 +308,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
let formatFunc = kbn.valueFormats[this.panel.format];
|
let formatFunc = kbn.valueFormats[this.panel.format];
|
||||||
data.value = lastPoint[1];
|
data.value = lastPoint[1];
|
||||||
data.valueRounded = data.value;
|
data.valueRounded = data.value;
|
||||||
data.valueFormatted = formatFunc(data.value, 0, 0);
|
data.valueFormatted = formatFunc(data.value, this.dashboard.isTimezoneUtc());
|
||||||
} else {
|
} else {
|
||||||
data.value = this.series[0].stats[this.panel.valueName];
|
data.value = this.series[0].stats[this.panel.valueName];
|
||||||
data.flotpairs = this.series[0].flotpairs;
|
data.flotpairs = this.series[0].flotpairs;
|
||||||
|
@ -82,6 +82,19 @@ describe('SingleStatCtrl', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
singleStatScenario('showing last iso time instead of value (in UTC)', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.data = [{ target: 'test.cpu1', datapoints: [[10, 12], [20, 1505634997920]] }];
|
||||||
|
ctx.ctrl.panel.valueName = 'last_time';
|
||||||
|
ctx.ctrl.panel.format = 'dateTimeAsIso';
|
||||||
|
ctx.setIsUtc(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set formatted value', function() {
|
||||||
|
expect(ctx.data.valueFormatted).to.be(moment.utc(1505634997920).format('YYYY-MM-DD HH:mm:ss'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
singleStatScenario('showing last us time instead of value', function(ctx) {
|
singleStatScenario('showing last us time instead of value', function(ctx) {
|
||||||
ctx.setup(function() {
|
ctx.setup(function() {
|
||||||
ctx.data = [{ target: 'test.cpu1', datapoints: [[10, 12], [20, 1505634997920]] }];
|
ctx.data = [{ target: 'test.cpu1', datapoints: [[10, 12], [20, 1505634997920]] }];
|
||||||
@ -99,6 +112,19 @@ describe('SingleStatCtrl', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
singleStatScenario('showing last us time instead of value (in UTC)', function(ctx) {
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.data = [{ target: 'test.cpu1', datapoints: [[10, 12], [20, 1505634997920]] }];
|
||||||
|
ctx.ctrl.panel.valueName = 'last_time';
|
||||||
|
ctx.ctrl.panel.format = 'dateTimeAsUS';
|
||||||
|
ctx.setIsUtc(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set formatted value', function() {
|
||||||
|
expect(ctx.data.valueFormatted).to.be(moment.utc(1505634997920).format('MM/DD/YYYY h:mm:ss a'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
singleStatScenario('showing last time from now instead of value', function(ctx) {
|
singleStatScenario('showing last time from now instead of value', function(ctx) {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
clock = sinon.useFakeTimers(epoch);
|
clock = sinon.useFakeTimers(epoch);
|
||||||
@ -124,6 +150,27 @@ describe('SingleStatCtrl', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
singleStatScenario('showing last time from now instead of value (in UTC)', function(ctx) {
|
||||||
|
beforeEach(() => {
|
||||||
|
clock = sinon.useFakeTimers(epoch);
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx.setup(function() {
|
||||||
|
ctx.data = [{ target: 'test.cpu1', datapoints: [[10, 12], [20, 1505634997920]] }];
|
||||||
|
ctx.ctrl.panel.valueName = 'last_time';
|
||||||
|
ctx.ctrl.panel.format = 'dateTimeFromNow';
|
||||||
|
ctx.setIsUtc(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set formatted value', function() {
|
||||||
|
expect(ctx.data.valueFormatted).to.be('2 days ago');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
clock.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
singleStatScenario('MainValue should use same number for decimals as displayed when checking thresholds', function(
|
singleStatScenario('MainValue should use same number for decimals as displayed when checking thresholds', function(
|
||||||
ctx
|
ctx
|
||||||
) {
|
) {
|
||||||
|
@ -23,6 +23,7 @@ export function ControllerTestContext() {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
this.isUtc = false;
|
||||||
|
|
||||||
this.providePhase = function(mocks) {
|
this.providePhase = function(mocks) {
|
||||||
return angularMocks.module(function($provide) {
|
return angularMocks.module(function($provide) {
|
||||||
@ -46,6 +47,10 @@ export function ControllerTestContext() {
|
|||||||
self.$q = $q;
|
self.$q = $q;
|
||||||
self.panel = new PanelModel({ type: 'test' });
|
self.panel = new PanelModel({ type: 'test' });
|
||||||
self.dashboard = { meta: {} };
|
self.dashboard = { meta: {} };
|
||||||
|
self.isUtc = false;
|
||||||
|
self.dashboard.isTimezoneUtc = function() {
|
||||||
|
return self.isUtc;
|
||||||
|
};
|
||||||
|
|
||||||
$rootScope.appEvent = sinon.spy();
|
$rootScope.appEvent = sinon.spy();
|
||||||
$rootScope.onAppEvent = sinon.spy();
|
$rootScope.onAppEvent = sinon.spy();
|
||||||
@ -93,6 +98,10 @@ export function ControllerTestContext() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.setIsUtc = function(isUtc = false) {
|
||||||
|
self.isUtc = isUtc;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ServiceTestContext() {
|
export function ServiceTestContext() {
|
||||||
|
Loading…
Reference in New Issue
Block a user