rangeutil.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // @ts-ignore
  2. import _ from 'lodash';
  3. import moment from 'moment';
  4. import { RawTimeRange } from '@grafana/ui';
  5. import * as dateMath from './datemath';
  6. const spans: { [key: string]: { display: string; section?: number } } = {
  7. s: { display: 'second' },
  8. m: { display: 'minute' },
  9. h: { display: 'hour' },
  10. d: { display: 'day' },
  11. w: { display: 'week' },
  12. M: { display: 'month' },
  13. y: { display: 'year' },
  14. };
  15. const rangeOptions = [
  16. { from: 'now/d', to: 'now/d', display: 'Today', section: 2 },
  17. { from: 'now/d', to: 'now', display: 'Today so far', section: 2 },
  18. { from: 'now/w', to: 'now/w', display: 'This week', section: 2 },
  19. { from: 'now/w', to: 'now', display: 'This week so far', section: 2 },
  20. { from: 'now/M', to: 'now/M', display: 'This month', section: 2 },
  21. { from: 'now/M', to: 'now', display: 'This month so far', section: 2 },
  22. { from: 'now/y', to: 'now/y', display: 'This year', section: 2 },
  23. { from: 'now/y', to: 'now', display: 'This year so far', section: 2 },
  24. { from: 'now-1d/d', to: 'now-1d/d', display: 'Yesterday', section: 1 },
  25. {
  26. from: 'now-2d/d',
  27. to: 'now-2d/d',
  28. display: 'Day before yesterday',
  29. section: 1,
  30. },
  31. {
  32. from: 'now-7d/d',
  33. to: 'now-7d/d',
  34. display: 'This day last week',
  35. section: 1,
  36. },
  37. { from: 'now-1w/w', to: 'now-1w/w', display: 'Previous week', section: 1 },
  38. { from: 'now-1M/M', to: 'now-1M/M', display: 'Previous month', section: 1 },
  39. { from: 'now-1y/y', to: 'now-1y/y', display: 'Previous year', section: 1 },
  40. { from: 'now-5m', to: 'now', display: 'Last 5 minutes', section: 3 },
  41. { from: 'now-15m', to: 'now', display: 'Last 15 minutes', section: 3 },
  42. { from: 'now-30m', to: 'now', display: 'Last 30 minutes', section: 3 },
  43. { from: 'now-1h', to: 'now', display: 'Last 1 hour', section: 3 },
  44. { from: 'now-3h', to: 'now', display: 'Last 3 hours', section: 3 },
  45. { from: 'now-6h', to: 'now', display: 'Last 6 hours', section: 3 },
  46. { from: 'now-12h', to: 'now', display: 'Last 12 hours', section: 3 },
  47. { from: 'now-24h', to: 'now', display: 'Last 24 hours', section: 3 },
  48. { from: 'now-2d', to: 'now', display: 'Last 2 days', section: 0 },
  49. { from: 'now-7d', to: 'now', display: 'Last 7 days', section: 0 },
  50. { from: 'now-30d', to: 'now', display: 'Last 30 days', section: 0 },
  51. { from: 'now-90d', to: 'now', display: 'Last 90 days', section: 0 },
  52. { from: 'now-6M', to: 'now', display: 'Last 6 months', section: 0 },
  53. { from: 'now-1y', to: 'now', display: 'Last 1 year', section: 0 },
  54. { from: 'now-2y', to: 'now', display: 'Last 2 years', section: 0 },
  55. { from: 'now-5y', to: 'now', display: 'Last 5 years', section: 0 },
  56. ];
  57. const absoluteFormat = 'MMM D, YYYY HH:mm:ss';
  58. const rangeIndex: any = {};
  59. _.each(rangeOptions, (frame: any) => {
  60. rangeIndex[frame.from + ' to ' + frame.to] = frame;
  61. });
  62. export function getRelativeTimesList(timepickerSettings: any, currentDisplay: any) {
  63. const groups = _.groupBy(rangeOptions, (option: any) => {
  64. option.active = option.display === currentDisplay;
  65. return option.section;
  66. });
  67. // _.each(timepickerSettings.time_options, (duration: string) => {
  68. // let info = describeTextRange(duration);
  69. // if (info.section) {
  70. // groups[info.section].push(info);
  71. // }
  72. // });
  73. return groups;
  74. }
  75. function formatDate(date: any) {
  76. return date.format(absoluteFormat);
  77. }
  78. // handles expressions like
  79. // 5m
  80. // 5m to now/d
  81. // now/d to now
  82. // now/d
  83. // if no to <expr> then to now is assumed
  84. export function describeTextRange(expr: any) {
  85. const isLast = expr.indexOf('+') !== 0;
  86. if (expr.indexOf('now') === -1) {
  87. expr = (isLast ? 'now-' : 'now') + expr;
  88. }
  89. let opt = rangeIndex[expr + ' to now'];
  90. if (opt) {
  91. return opt;
  92. }
  93. if (isLast) {
  94. opt = { from: expr, to: 'now' };
  95. } else {
  96. opt = { from: 'now', to: expr };
  97. }
  98. const parts = /^now([-+])(\d+)(\w)/.exec(expr);
  99. if (parts) {
  100. const unit = parts[3];
  101. const amount = parseInt(parts[2], 10);
  102. const span = spans[unit];
  103. if (span) {
  104. opt.display = isLast ? 'Last ' : 'Next ';
  105. opt.display += amount + ' ' + span.display;
  106. opt.section = span.section;
  107. if (amount > 1) {
  108. opt.display += 's';
  109. }
  110. }
  111. } else {
  112. opt.display = opt.from + ' to ' + opt.to;
  113. opt.invalid = true;
  114. }
  115. return opt;
  116. }
  117. export function describeTimeRange(range: RawTimeRange): string {
  118. const option = rangeIndex[range.from.toString() + ' to ' + range.to.toString()];
  119. if (option) {
  120. return option.display;
  121. }
  122. if (moment.isMoment(range.from) && moment.isMoment(range.to)) {
  123. return formatDate(range.from) + ' to ' + formatDate(range.to);
  124. }
  125. if (moment.isMoment(range.from)) {
  126. const toMoment = dateMath.parse(range.to, true);
  127. return toMoment ? formatDate(range.from) + ' to ' + toMoment.fromNow() : '';
  128. }
  129. if (moment.isMoment(range.to)) {
  130. const from = dateMath.parse(range.from, false);
  131. return from ? from.fromNow() + ' to ' + formatDate(range.to) : '';
  132. }
  133. if (range.to.toString() === 'now') {
  134. const res = describeTextRange(range.from);
  135. return res.display;
  136. }
  137. return range.from.toString() + ' to ' + range.to.toString();
  138. }
  139. export const isValidTimeSpan = (value: string) => {
  140. if (value.indexOf('$') === 0 || value.indexOf('+$') === 0) {
  141. return true;
  142. }
  143. const info = describeTextRange(value);
  144. return info.invalid !== true;
  145. };