Add duration unit format (#2483)
* chore: 🤖 add @formatjs/intl-durationformat to addons/core * refactor: 💡 replace old duration format with new package * chore: 🤖 remove intl-unofficial-duration-unit-format * Add missing copyright headers * test: 💍 add more test cases --------- Co-authored-by: cameronperera <cameronperera@users.noreply.github.com>
This commit is contained in:
1 parent
e395b1196c
commit
9648e1fa3b
8 files changed
+157
-24
No files matched your search
@@ -5,7 +5,8 @@
|
||||
|
||||
import Helper from '@ember/component/helper';
|
||||
import { inject as service } from '@ember/service';
|
||||
import DurationUnitFormat from 'intl-unofficial-duration-unit-format';
|
||||
import { DurationFormat } from '@formatjs/intl-durationformat';
|
||||
import { secondsToDuration } from 'core/utils/seconds-to-duration';
|
||||
|
||||
export default class extends Helper {
|
||||
// =services
|
||||
@@ -19,12 +20,10 @@ export default class extends Helper {
|
||||
*/
|
||||
compute([durationInMs]) {
|
||||
const durationInSeconds = durationInMs / 1000;
|
||||
const durationFormat = new DurationUnitFormat(this.intl.primaryLocale, {
|
||||
const durationFormat = new DurationFormat(this.intl.primaryLocale, {
|
||||
style: 'narrow',
|
||||
format: '{days} {hours} {minutes} {seconds}',
|
||||
round: true,
|
||||
});
|
||||
|
||||
return durationFormat.format(durationInSeconds);
|
||||
return durationFormat.format(secondsToDuration(durationInSeconds));
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
import Helper from '@ember/component/helper';
|
||||
import { inject as service } from '@ember/service';
|
||||
import DurationUnitFormat from 'intl-unofficial-duration-unit-format';
|
||||
import { DurationFormat } from '@formatjs/intl-durationformat';
|
||||
import { secondsToDuration } from 'core/utils/seconds-to-duration';
|
||||
|
||||
export default class extends Helper {
|
||||
// =services
|
||||
@@ -29,14 +30,13 @@ export default class extends Helper {
|
||||
difference > 0 ? Math.floor(difference / 1000) : 0;
|
||||
|
||||
// Format the duration
|
||||
const duration = new DurationUnitFormat(this.intl.primaryLocale, {
|
||||
style: 'timer',
|
||||
format: `{hours}:{minutes}:{seconds} ${this.intl.t(
|
||||
'resources.session.remaining',
|
||||
)}`,
|
||||
const duration = new DurationFormat(this.intl.primaryLocale, {
|
||||
style: 'digital',
|
||||
});
|
||||
const formattedTime = duration.format(
|
||||
secondsToDuration(differenceInSeconds),
|
||||
);
|
||||
|
||||
// Return the formatted duration
|
||||
return duration.format(differenceInSeconds);
|
||||
return `${formattedTime} ${this.intl.t('resources.session.remaining')}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Takes in the number of seconds and converts to an object with corresponding
|
||||
* values for each time duration. For example:
|
||||
* { weeks: 0, days: 0, hours: 22, minutes: 15, seconds: 11 }
|
||||
* @param {number} value
|
||||
* @returns {object}
|
||||
*/
|
||||
export const secondsToDuration = (value) => {
|
||||
const second = 1;
|
||||
const minute = second * 60;
|
||||
const hour = minute * 60;
|
||||
const day = hour * 24;
|
||||
const week = day * 7;
|
||||
|
||||
const weeks = Math.max(Math.floor(value / week), 0);
|
||||
const days = Math.max(Math.floor((value % week) / day), 0);
|
||||
const hours = Math.max(Math.floor((value % day) / hour), 0);
|
||||
const minutes = Math.max(Math.floor((value % hour) / minute), 0);
|
||||
const seconds = Math.max(Math.floor((value % minute) / second), 0);
|
||||
|
||||
return { weeks, days, hours, minutes, seconds };
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export { default } from 'core/utils/seconds-to-duration';
|
||||
@@ -31,6 +31,7 @@
|
||||
"doc:toc": "doctoc README.md"
|
||||
},
|
||||
"dependencies": {
|
||||
"@formatjs/intl-durationformat": "^0.2.4",
|
||||
"api": "*",
|
||||
"auth": "*",
|
||||
"ember-auto-import": "^2.6.3",
|
||||
@@ -43,7 +44,6 @@
|
||||
"ember-loading": "^2.0.0",
|
||||
"ember-truth-helpers": "^3.0.0",
|
||||
"filesize": "^10.0.7",
|
||||
"intl-unofficial-duration-unit-format": "^3.1.0",
|
||||
"sass": "^1.69.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -13,9 +13,7 @@ module('Integration | Helper | time-remaining', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
test('it calculates the correct time remaining', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
test('it calculates the correct time remainin with less than 24 hours', async function (assert) {
|
||||
this.set('expirationTime', new Date(Date.now() + 1000 * 60 * 60 * 24));
|
||||
|
||||
await render(hbs`{{time-remaining this.expirationTime}}`);
|
||||
@@ -23,9 +21,29 @@ module('Integration | Helper | time-remaining', function (hooks) {
|
||||
assert.strictEqual(this.element.textContent.trim(), '23:59:59 remaining');
|
||||
});
|
||||
|
||||
test('it handles negative time remaining', async function (assert) {
|
||||
assert.expect(1);
|
||||
test('it calculates the correct time remaining with more than 24 hours', async function (assert) {
|
||||
this.set('expirationTime', new Date(Date.now() + 1001 * 60 * 60 * 24));
|
||||
|
||||
await render(hbs`{{time-remaining this.expirationTime}}`);
|
||||
|
||||
assert.strictEqual(
|
||||
this.element.textContent.trim(),
|
||||
'1 day, 0:01:26 remaining',
|
||||
);
|
||||
});
|
||||
|
||||
test('it calculates the correct time remaining with more than a week', async function (assert) {
|
||||
this.set('expirationTime', new Date(Date.now() + 1001 * 60 * 60 * 24 * 8));
|
||||
|
||||
await render(hbs`{{time-remaining this.expirationTime}}`);
|
||||
|
||||
assert.strictEqual(
|
||||
this.element.textContent.trim(),
|
||||
'1 wk, 1 day, 0:11:31 remaining',
|
||||
);
|
||||
});
|
||||
|
||||
test('it handles negative time remaining', async function (assert) {
|
||||
this.set('expirationTime', new Date(Date.now() - 1000 * 60 * 60 * 24));
|
||||
|
||||
await render(hbs`{{time-remaining this.expirationTime}}`);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { secondsToDuration } from 'core/utils/seconds-to-duration';
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
module('Unit | Utility | seconds-to-duration', function () {
|
||||
test('it handles 0 correctly', function (assert) {
|
||||
const result = secondsToDuration(0);
|
||||
|
||||
assert.strictEqual(result.seconds, 0);
|
||||
assert.strictEqual(result.minutes, 0);
|
||||
assert.strictEqual(result.hours, 0);
|
||||
assert.strictEqual(result.days, 0);
|
||||
assert.strictEqual(result.weeks, 0);
|
||||
});
|
||||
|
||||
test('it converts seconds correctly', function (assert) {
|
||||
const result = secondsToDuration(45);
|
||||
|
||||
assert.strictEqual(result.seconds, 45);
|
||||
assert.strictEqual(result.minutes, 0);
|
||||
assert.strictEqual(result.hours, 0);
|
||||
assert.strictEqual(result.days, 0);
|
||||
assert.strictEqual(result.weeks, 0);
|
||||
});
|
||||
|
||||
test('it converts minutes correctly', function (assert) {
|
||||
const result = secondsToDuration(100);
|
||||
|
||||
assert.strictEqual(result.seconds, 40);
|
||||
assert.strictEqual(result.minutes, 1);
|
||||
assert.strictEqual(result.hours, 0);
|
||||
assert.strictEqual(result.days, 0);
|
||||
assert.strictEqual(result.weeks, 0);
|
||||
});
|
||||
|
||||
test('it converts hours correctly', function (assert) {
|
||||
const result = secondsToDuration(5000);
|
||||
|
||||
assert.strictEqual(result.seconds, 20);
|
||||
assert.strictEqual(result.minutes, 23);
|
||||
assert.strictEqual(result.hours, 1);
|
||||
assert.strictEqual(result.days, 0);
|
||||
assert.strictEqual(result.weeks, 0);
|
||||
});
|
||||
|
||||
test('it converts days correctly', function (assert) {
|
||||
const result = secondsToDuration(500000);
|
||||
|
||||
assert.strictEqual(result.seconds, 20);
|
||||
assert.strictEqual(result.minutes, 53);
|
||||
assert.strictEqual(result.hours, 18);
|
||||
assert.strictEqual(result.days, 5);
|
||||
assert.strictEqual(result.weeks, 0);
|
||||
});
|
||||
|
||||
test('it converts weeks correctly', function (assert) {
|
||||
const result = secondsToDuration(800000);
|
||||
|
||||
assert.strictEqual(result.seconds, 20);
|
||||
assert.strictEqual(result.minutes, 13);
|
||||
assert.strictEqual(result.hours, 6);
|
||||
assert.strictEqual(result.days, 2);
|
||||
assert.strictEqual(result.weeks, 1);
|
||||
});
|
||||
|
||||
test('it handles negative values', function (assert) {
|
||||
const result = secondsToDuration(-800000);
|
||||
|
||||
assert.strictEqual(result.seconds, 0);
|
||||
assert.strictEqual(result.minutes, 0);
|
||||
assert.strictEqual(result.hours, 0);
|
||||
assert.strictEqual(result.days, 0);
|
||||
assert.strictEqual(result.weeks, 0);
|
||||
});
|
||||
});
|
||||
@@ -3981,6 +3981,15 @@
|
||||
"@formatjs/intl-localematcher" "0.5.4"
|
||||
tslib "^2.4.0"
|
||||
|
||||
"@formatjs/intl-durationformat@^0.2.4":
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-durationformat/-/intl-durationformat-0.2.4.tgz#ac3c46a0b104ca8635afc9bf5aa8be2274ecd200"
|
||||
integrity sha512-wtmC8eZeIkyQ8fVWdarAjNbqOkAq0wQ7GBoG6aBIK0+O9wU5gq9l0jOpKYymdQq4Hz3lZKpgXgXcZm+Z40w4Rw==
|
||||
dependencies:
|
||||
"@formatjs/ecma402-abstract" "2.0.0"
|
||||
"@formatjs/intl-localematcher" "0.5.4"
|
||||
tslib "^2.4.0"
|
||||
|
||||
"@formatjs/intl-listformat@7.5.7":
|
||||
version "7.5.7"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.5.7.tgz#125e05105fabd1ae5f11881d6ab74484f2098ee4"
|
||||
@@ -12146,11 +12155,6 @@ intl-messageformat@10.5.14, intl-messageformat@^10.5.14:
|
||||
"@formatjs/icu-messageformat-parser" "2.7.8"
|
||||
tslib "^2.4.0"
|
||||
|
||||
intl-unofficial-duration-unit-format@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/intl-unofficial-duration-unit-format/-/intl-unofficial-duration-unit-format-3.1.0.tgz#994feefc8d903d9e5044dc7e4e1d38ebad59394b"
|
||||
integrity sha512-yjvUDwV63zSGkbeUqpDRJmOgMQoJA8OFhNeo+1KY20q+lFCtcvRWszJNsq/ssrUJRy8g+Mt3BYNfwFvRRSAkow==
|
||||
|
||||
invert-kv@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-3.0.1.tgz#a93c7a3d4386a1dc8325b97da9bb1620c0282523"
|
||||
|
||||
Reference in new issue
Block a user