mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Allow future relative time (#89405)
This commit is contained in:
parent
d8137083d9
commit
b7910ade97
@ -40,6 +40,17 @@ describe('utils', () => {
|
|||||||
display: 'now-100m to now-5m',
|
display: 'now-100m to now-5m',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to work with future values', () => {
|
||||||
|
const relativeTimeRange = { from: 600, to: -600 };
|
||||||
|
const timeOption = mapRelativeTimeRangeToOption(relativeTimeRange);
|
||||||
|
|
||||||
|
expect(timeOption).toEqual({
|
||||||
|
from: 'now-10m',
|
||||||
|
to: 'now+10m',
|
||||||
|
display: 'now-10m to now+10m',
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('mapOptionToRelativeTimeRange', () => {
|
describe('mapOptionToRelativeTimeRange', () => {
|
||||||
@ -56,6 +67,13 @@ describe('utils', () => {
|
|||||||
|
|
||||||
expect(relativeTimeRange).toEqual({ from: 86400, to: 43200 });
|
expect(relativeTimeRange).toEqual({ from: 86400, to: 43200 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should map future dates', () => {
|
||||||
|
const timeOption = { from: 'now-10m', to: 'now+10m', display: 'asdfasdf' };
|
||||||
|
const relativeTimeRange = mapOptionToRelativeTimeRange(timeOption);
|
||||||
|
|
||||||
|
expect(relativeTimeRange).toEqual({ from: 600, to: -600 });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isRelativeFormat', () => {
|
describe('isRelativeFormat', () => {
|
||||||
@ -83,6 +101,10 @@ describe('utils', () => {
|
|||||||
expect(isRelativeFormat('now-53w')).toBe(true);
|
expect(isRelativeFormat('now-53w')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should consider now+10m as a relative format', () => {
|
||||||
|
expect(isRelativeFormat('now+10m')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it('should consider 123123123 as a relative format', () => {
|
it('should consider 123123123 as a relative format', () => {
|
||||||
expect(isRelativeFormat('123123123')).toBe(false);
|
expect(isRelativeFormat('123123123')).toBe(false);
|
||||||
});
|
});
|
||||||
@ -99,6 +121,11 @@ describe('utils', () => {
|
|||||||
expect(result.isValid).toBe(true);
|
expect(result.isValid).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should consider now+10m as a valid relative format', () => {
|
||||||
|
const result = isRangeValid('now+10m');
|
||||||
|
expect(result.isValid).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it('should consider now-90000000d as an invalid relative format', () => {
|
it('should consider now-90000000d as an invalid relative format', () => {
|
||||||
const result = isRangeValid('now-90000000d');
|
const result = isRangeValid('now-90000000d');
|
||||||
expect(result.isValid).toBe(false);
|
expect(result.isValid).toBe(false);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { RelativeTimeRange, TimeOption } from '@grafana/data';
|
import { RelativeTimeRange, TimeOption } from '@grafana/data';
|
||||||
|
|
||||||
const regex = /^now$|^now\-(\d{1,10})([wdhms])$/;
|
const regex = /^now$|^now(\-|\+)(\d{1,10})([wdhms])$/;
|
||||||
|
|
||||||
export const mapOptionToRelativeTimeRange = (option: TimeOption): RelativeTimeRange | undefined => {
|
export const mapOptionToRelativeTimeRange = (option: TimeOption): RelativeTimeRange | undefined => {
|
||||||
return {
|
return {
|
||||||
@ -48,18 +48,19 @@ export const isRelativeFormat = (format: string): boolean => {
|
|||||||
const relativeToSeconds = (relative: string): number => {
|
const relativeToSeconds = (relative: string): number => {
|
||||||
const match = regex.exec(relative);
|
const match = regex.exec(relative);
|
||||||
|
|
||||||
if (!match || match.length !== 3) {
|
if (!match || match.length !== 4) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [, value, unit] = match;
|
const [, sign, value, unit] = match;
|
||||||
const parsed = parseInt(value, 10);
|
const parsed = parseInt(value, 10);
|
||||||
|
|
||||||
if (isNaN(parsed)) {
|
if (isNaN(parsed)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsed * units[unit];
|
const seconds = parsed * units[unit];
|
||||||
|
return sign === '+' ? seconds * -1 : seconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
const units: Record<string, number> = {
|
const units: Record<string, number> = {
|
||||||
@ -71,25 +72,41 @@ const units: Record<string, number> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const secondsToRelativeFormat = (seconds: number): string => {
|
const secondsToRelativeFormat = (seconds: number): string => {
|
||||||
if (seconds <= 0) {
|
if (seconds === 0) {
|
||||||
return 'now';
|
return 'now';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seconds >= units.w && seconds % units.w === 0) {
|
const absoluteSeconds = Math.abs(seconds);
|
||||||
return `now-${seconds / units.w}w`;
|
if (seconds < 0) {
|
||||||
|
return `now+${formatDuration(absoluteSeconds)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seconds >= units.d && seconds % units.d === 0) {
|
return `now-${formatDuration(absoluteSeconds)}`;
|
||||||
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`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the given duration in seconds into a human-readable string representation.
|
||||||
|
*
|
||||||
|
* @param seconds - The duration in seconds.
|
||||||
|
* @returns The formatted duration string.
|
||||||
|
*/
|
||||||
|
function formatDuration(seconds: number): string {
|
||||||
|
const units = [
|
||||||
|
{ unit: 'w', value: 7 * 24 * 60 * 60 },
|
||||||
|
{ unit: 'd', value: 24 * 60 * 60 },
|
||||||
|
{ unit: 'h', value: 60 * 60 },
|
||||||
|
{ unit: 'm', value: 60 },
|
||||||
|
{ unit: 's', value: 1 },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const { unit, value } of units) {
|
||||||
|
if (seconds % value === 0) {
|
||||||
|
const quotient = seconds / value;
|
||||||
|
return `${quotient}${unit}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no perfect division, use the least significant unit
|
||||||
|
const leastSignificant = units[units.length - 1];
|
||||||
|
return `${seconds}${leastSignificant.unit}`;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user