mirror of
https://github.com/grafana/grafana.git
synced 2025-02-12 00:25:46 -06:00
- use global range types - add ErrorBoundary around individual Explore components - fix table merge on empty results - fix TimePicker date parsing on ISO dates - fix TimePicker range string after relative move
162 lines
4.9 KiB
TypeScript
162 lines
4.9 KiB
TypeScript
import _ from 'lodash';
|
|
import moment from 'moment';
|
|
|
|
import { RawTimeRange } from 'app/types/series';
|
|
|
|
import * as dateMath from './datemath';
|
|
|
|
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 <expr> 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();
|
|
}
|