Stabilize logging, correlation IDs, service-account Jira auth, and direct approver reminder DMs while splitting the monolith into focused modules with Compose-based deployment. Co-authored-by: Cursor <cursoragent@cursor.com>
30 lines
1,012 B
JavaScript
30 lines
1,012 B
JavaScript
export function sleep(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
export function formatDuration(timestamp, locale = 'en') {
|
|
let value;
|
|
const diff = (new Date().getTime() - new Date(timestamp).getTime()) / 1000;
|
|
const minutes = Math.floor(diff / 60);
|
|
const hours = Math.floor(minutes / 60);
|
|
const days = Math.floor(hours / 24);
|
|
const months = Math.floor(days / 30);
|
|
const years = Math.floor(months / 12);
|
|
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
|
|
|
|
if (years > 0) {
|
|
value = rtf.format(0 - years, 'year');
|
|
} else if (months > 0) {
|
|
value = rtf.format(0 - months, 'month');
|
|
} else if (days > 0) {
|
|
value = rtf.format(0 - days, 'day');
|
|
} else if (hours > 0) {
|
|
value = rtf.format(0 - hours, 'hour');
|
|
} else if (minutes > 0) {
|
|
value = rtf.format(0 - minutes, 'minute');
|
|
} else {
|
|
value = rtf.format(0 - diff, 'second');
|
|
}
|
|
|
|
return `(Submitted ${value})`;
|
|
}
|