Files
Marcus Andersson 07ef4060a3 Alerting: adding a time picker for selecting relative time. (#33689)
* adding placeholder for relative time range.

* fixed story.

* added basic structure to handle open/close of time range picker.

* removed section from TimeOptions since it isn't used any where.

* adding mapper and tests

* move relativetimepicker to its own dir

* added some simple tests.

* changed test.

* use relativetimerangeinput

* redo state management

* refactored the tests.

* replace timerange with relativetimerange

* wip

* wip

* did some refactoring.

* refactored time option formatting.

* added proper formatting and display of time range.

* add relative time description, slight refactor of height

* fixed incorrect import.

* added validator and changed formatting.

* removed unused dep.

* reverted back to internal function.

* fixed display of relative time range picker.

* fixed failing tests.

* fixed parsing issue.

* fixed position of time range picker.

* some more refactorings.

* fixed validation of really big values.

* added another test.

Co-authored-by: Peter Holmberg <peter.hlmbrg@gmail.com>
2021-05-12 17:51:31 +02:00

84 lines
1.8 KiB
TypeScript

import { RelativeTimeRange, TimeOption } from '@grafana/data';
const regex = /^now$|^now\-(\d{1,10})([wdhms])$/;
export const mapOptionToRelativeTimeRange = (option: TimeOption): RelativeTimeRange | undefined => {
return {
from: relativeToSeconds(option.from),
to: relativeToSeconds(option.to),
};
};
export const mapRelativeTimeRangeToOption = (range: RelativeTimeRange): TimeOption => {
const from = secondsToRelativeFormat(range.from);
const to = secondsToRelativeFormat(range.to);
return { from, to, display: `${from} to ${to}` };
};
export const isRangeValid = (relative: string, now = Date.now()): boolean => {
if (!isRelativeFormat(relative)) {
return false;
}
const seconds = relativeToSeconds(relative);
if (seconds > Math.ceil(now / 1000)) {
return false;
}
return true;
};
export const isRelativeFormat = (format: string): boolean => {
return regex.test(format);
};
const relativeToSeconds = (relative: string): number => {
const match = regex.exec(relative);
if (!match || match.length !== 3) {
return 0;
}
const [, value, unit] = match;
const parsed = parseInt(value, 10);
if (isNaN(parsed)) {
return 0;
}
return parsed * units[unit];
};
const units: Record<string, number> = {
w: 604800,
d: 86400,
h: 3600,
m: 60,
s: 1,
};
const secondsToRelativeFormat = (seconds: number): string => {
if (seconds <= 0) {
return 'now';
}
if (seconds >= units.w && seconds % units.w === 0) {
return `now-${seconds / units.w}w`;
}
if (seconds >= units.d && seconds % units.d === 0) {
return `now-${seconds / units.d}d`;
}
if (seconds >= units.h && seconds % units.h === 0) {
return `now-${seconds / units.h}h`;
}
if (seconds >= units.m && seconds % units.m === 0) {
return `now-${seconds / units.m}m`;
}
return `now-${seconds}s`;
};