Alerting: Add duration field to silence editor (#34029)
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
import { intervalToAbbreviatedDurationString, addDurationToDate, parseDuration } from './durationutil';
|
||||
|
||||
describe('Duration util', () => {
|
||||
describe('intervalToAbbreviatedDurationString', () => {
|
||||
it('creates a duration string for a provided interval', () => {
|
||||
const startDate = new Date();
|
||||
const endDate = addDurationToDate(startDate, { months: 1, weeks: 1, days: 1, hours: 1, minutes: 1, seconds: 1 });
|
||||
expect(intervalToAbbreviatedDurationString({ start: startDate, end: endDate })).toEqual('1M 8d 1h 1m 1s');
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseDuration', () => {
|
||||
it('parses a duration string', () => {
|
||||
const durationString = '3M 5d 20m';
|
||||
expect(parseDuration(durationString)).toEqual({ months: '3', days: '5', minutes: '20' });
|
||||
});
|
||||
|
||||
it('strips out non valid durations', () => {
|
||||
const durationString = '3M 6v 5b 4m';
|
||||
expect(parseDuration(durationString)).toEqual({ months: '3', minutes: '4' });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Duration, Interval } from 'date-fns';
|
||||
import intervalToDuration from 'date-fns/intervalToDuration';
|
||||
import add from 'date-fns/add';
|
||||
|
||||
const durationMap: { [key in Required<keyof Duration>]: string[] } = {
|
||||
years: ['y', 'Y', 'years'],
|
||||
months: ['M', 'months'],
|
||||
weeks: ['w', 'W', 'weeks'],
|
||||
days: ['d', 'D', 'days'],
|
||||
hours: ['h', 'H', 'hours'],
|
||||
minutes: ['m', 'minutes'],
|
||||
seconds: ['s', 'S', 'seconds'],
|
||||
};
|
||||
|
||||
export function intervalToAbbreviatedDurationString(interval: Interval): string {
|
||||
const duration = intervalToDuration(interval);
|
||||
return (Object.entries(duration) as Array<[keyof Duration, number | undefined]>).reduce((str, [unit, value]) => {
|
||||
if (value && value !== 0) {
|
||||
const padding = str !== '' ? ' ' : '';
|
||||
return str + `${padding}${value}${durationMap[unit][0]}`;
|
||||
}
|
||||
|
||||
return str;
|
||||
}, '');
|
||||
}
|
||||
|
||||
export function parseDuration(duration: string): Duration {
|
||||
return duration.split(' ').reduce<Duration>((acc, value) => {
|
||||
const match = value.match(/(\d+)(.+)/);
|
||||
if (match === null || match.length !== 3) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
const key = Object.entries(durationMap).find(([_, abbreviations]) => abbreviations?.includes(match[2]))?.[0];
|
||||
return !key ? acc : { ...acc, [key]: match[1] };
|
||||
}, {});
|
||||
}
|
||||
|
||||
export function addDurationToDate(date: Date | number, duration: Duration): Date {
|
||||
return add(date, duration);
|
||||
}
|
||||
|
||||
export function isValidDate(dateString: string) {
|
||||
return !isNaN(Date.parse(dateString));
|
||||
}
|
||||
@@ -6,5 +6,6 @@ export * from './timezones';
|
||||
export * from './formats';
|
||||
export * from './formatter';
|
||||
export * from './parser';
|
||||
export * from './durationutil';
|
||||
export { dateMath, rangeUtil };
|
||||
export { DateTimeOptions, setTimeZoneResolver, TimeZoneResolver, getTimeZone } from './common';
|
||||
|
||||
Reference in New Issue
Block a user