From 9fb1db1b02ea5f6f8ce81ef2ae308fd5e3c29de5 Mon Sep 17 00:00:00 2001 From: Andrei Caleniuc Date: Fri, 31 Mar 2023 16:39:01 +0300 Subject: [PATCH] fix: humanize duration in different locales --- package-lock.json | 28 ++------------- package.json | 4 +-- .../src/ui-dateformat.directive.ts | 1 - .../ui-secondformat.directive.luxon.spec.ts | 35 +++++++++++++++++-- .../src/ui-secondformat.directive.ts | 29 +++++++++------ projects/angular/package.json | 3 +- 6 files changed, 56 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c44d6b27..ee73b888c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "angular-components", - "version": "14.5.3", + "version": "14.5.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "angular-components", - "version": "14.5.3", + "version": "14.5.4", "license": "MIT", "dependencies": { "@angular/animations": "14.2.12", @@ -20,7 +20,6 @@ "@angular/platform-browser-dynamic": "14.2.12", "@angular/router": "14.2.12", "clipboard": "2.0.8", - "humanize-duration": "3.28.0", "lodash-es": "4.17.21", "luxon": "3.2.1", "moment": "2.29.4", @@ -51,7 +50,6 @@ "@types/chalk": "^2.2.0", "@types/clipboard": "2.0.7", "@types/faker": "4.1.5", - "@types/humanize-duration": "3.27.1", "@types/jasmine": "3.3.12", "@types/jasmine_dom_matchers": "^1.4.4", "@types/jasminewd2": "2.0.6", @@ -5448,12 +5446,6 @@ "@types/node": "*" } }, - "node_modules/@types/humanize-duration": { - "version": "3.27.1", - "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.27.1.tgz", - "integrity": "sha512-K3e+NZlpCKd6Bd/EIdqjFJRFHbrq5TzPPLwREk5Iv/YoIjQrs6ljdAUCo+Lb2xFlGNOjGSE0dqsVD19cZL137w==", - "dev": true - }, "node_modules/@types/jasmine": { "version": "3.3.12", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.3.12.tgz", @@ -14365,11 +14357,6 @@ "node": ">=10.17.0" } }, - "node_modules/humanize-duration": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.28.0.tgz", - "integrity": "sha512-jMAxraOOmHuPbffLVDKkEKi/NeG8dMqP8lGRd6Tbf7JgAeG33jjgPWDbXXU7ypCI0o+oNKJFgbSB9FKVdWNI2A==" - }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -29583,12 +29570,6 @@ "@types/node": "*" } }, - "@types/humanize-duration": { - "version": "3.27.1", - "resolved": "https://registry.npmjs.org/@types/humanize-duration/-/humanize-duration-3.27.1.tgz", - "integrity": "sha512-K3e+NZlpCKd6Bd/EIdqjFJRFHbrq5TzPPLwREk5Iv/YoIjQrs6ljdAUCo+Lb2xFlGNOjGSE0dqsVD19cZL137w==", - "dev": true - }, "@types/jasmine": { "version": "3.3.12", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.3.12.tgz", @@ -36407,11 +36388,6 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, - "humanize-duration": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.28.0.tgz", - "integrity": "sha512-jMAxraOOmHuPbffLVDKkEKi/NeG8dMqP8lGRd6Tbf7JgAeG33jjgPWDbXXU7ypCI0o+oNKJFgbSB9FKVdWNI2A==" - }, "humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", diff --git a/package.json b/package.json index 1027c55e2..cd2281c47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-components", - "version": "14.5.3", + "version": "14.5.4", "author": { "name": "UiPath Inc", "url": "https://uipath.com" @@ -81,7 +81,6 @@ "@angular/platform-browser-dynamic": "14.2.12", "@angular/router": "14.2.12", "clipboard": "2.0.8", - "humanize-duration": "3.28.0", "lodash-es": "4.17.21", "luxon": "3.2.1", "moment": "2.29.4", @@ -112,7 +111,6 @@ "@types/chalk": "^2.2.0", "@types/clipboard": "2.0.7", "@types/faker": "4.1.5", - "@types/humanize-duration": "3.27.1", "@types/jasmine": "3.3.12", "@types/jasmine_dom_matchers": "^1.4.4", "@types/jasminewd2": "2.0.6", diff --git a/projects/angular/directives/ui-dateformat/src/ui-dateformat.directive.ts b/projects/angular/directives/ui-dateformat/src/ui-dateformat.directive.ts index bb438fb91..ab6251a1d 100644 --- a/projects/angular/directives/ui-dateformat/src/ui-dateformat.directive.ts +++ b/projects/angular/directives/ui-dateformat/src/ui-dateformat.directive.ts @@ -112,7 +112,6 @@ export const resolveTimezone = (options: IDateFormatOptions) => { * Optionally, you can opt-in to use Luxon instead of Moment. * Depends On: * - [luxon](https://www.npmjs.com/package/luxon) - * - [humanize-duration](https://www.npmjs.com/package/humanize-duration) * * @export */ diff --git a/projects/angular/directives/ui-secondformat/src/ui-secondformat.directive.luxon.spec.ts b/projects/angular/directives/ui-secondformat/src/ui-secondformat.directive.luxon.spec.ts index 6d6388ae5..d8c231dbe 100644 --- a/projects/angular/directives/ui-secondformat/src/ui-secondformat.directive.luxon.spec.ts +++ b/projects/angular/directives/ui-secondformat/src/ui-secondformat.directive.luxon.spec.ts @@ -1,3 +1,4 @@ +import { Settings } from 'luxon'; import { BehaviorSubject, firstValueFrom, @@ -13,9 +14,8 @@ import { waitForAsync, } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; - -import { Settings } from 'luxon'; import { USE_LUXON } from '@uipath/angular/utilities'; + import { ISecondFormatOptions, UiSecondFormatDirective, @@ -161,4 +161,35 @@ describe('Directive: UiSecondFormat with luxon', () => { expect(enTooltip).toBe(jaTooltip); }); }); + + describe('humanize in different locales', () => { + [ + { + code: 'es-mx', + unit: ' segundos', + }, + { + code: 'pt-br', + unit: ' segundos', + }, + { + code: 'zh-cn', + unit: '秒钟', + }, + ].forEach(locale => { + it(`should humanize in ${locale.code}`, async () => { + Settings.defaultLocale = locale.code; + + component.seconds = 40; + fixture.detectChanges(); + + const text = fixture.debugElement.query(By.directive(UiSecondFormatDirective)); + + (options.redraw$ as BehaviorSubject).next(); + + fixture.detectChanges(); + expect(text.nativeElement.innerText).toBe(`40${locale.unit}`); + }); + }); + }); }); diff --git a/projects/angular/directives/ui-secondformat/src/ui-secondformat.directive.ts b/projects/angular/directives/ui-secondformat/src/ui-secondformat.directive.ts index 1e82f25f7..2b150c127 100644 --- a/projects/angular/directives/ui-secondformat/src/ui-secondformat.directive.ts +++ b/projects/angular/directives/ui-secondformat/src/ui-secondformat.directive.ts @@ -1,5 +1,7 @@ -import humanizeDuration from 'humanize-duration'; -import { Duration } from 'luxon'; +import { + Duration, + DurationObjectUnits, +} from 'luxon'; import moment from 'moment'; import { BehaviorSubject, @@ -55,7 +57,6 @@ export const UI_SECONDFORMAT_OPTIONS = new InjectionToken>('UiS * Optionally, you can opt-in to use Luxon instead of Moment. * Depends On: * - [luxon](https://www.npmjs.com/package/luxon) - * - [humanize-duration](https://www.npmjs.com/package/humanize-duration) * * @export */ @@ -88,6 +89,8 @@ export class UiSecondFormatDirective { private _seconds$ = new BehaviorSubject(null); + private _units: (keyof DurationObjectUnits)[] = ['years', 'months', 'days', 'hours', 'minutes', 'seconds', 'milliseconds']; + /** * @ignore */ @@ -134,13 +137,15 @@ export class UiSecondFormatDirective { return ''; } - return moment.isDuration(duration) - ? duration.humanize() - : humanizeDuration(duration.toMillis(), { - language: duration.locale, - // Max number of units is set to 1 to mimic what moment does - largest: 1, - }); + if (moment.isDuration(duration)) { + return duration.humanize(); + } + + const rescaledDuration = duration.rescale(); + + const largestUnit = this._getDurationLargestUnit(rescaledDuration); + + return Duration.fromObject({ [largestUnit]: rescaledDuration[largestUnit] }).toHuman(); }; private _mapDurationToTooltip = (duration: Duration | moment.Duration | null) => { @@ -152,4 +157,8 @@ export class UiSecondFormatDirective { ? duration.toISOString() : duration.shiftTo('hours', 'minutes', 'seconds').toISO(); }; + + private _getDurationLargestUnit(duration: Duration) { + return this._units.find(unit => !!duration[unit]) ?? 'seconds'; + } } diff --git a/projects/angular/package.json b/projects/angular/package.json index 3352273f2..bdf7c5c4e 100644 --- a/projects/angular/package.json +++ b/projects/angular/package.json @@ -1,6 +1,6 @@ { "name": "@uipath/angular", - "version": "14.5.3", + "version": "14.5.4", "license": "MIT", "author": { "name": "UiPath Inc", @@ -39,7 +39,6 @@ "@angular/platform-browser-dynamic": ">=14.1.0", "@angular/router": ">=14.1.0", "clipboard": "^2.0.8", - "humanize-duration": "^3.28.0", "lodash-es": "^4.17.21", "luxon": "^3.2.1", "moment": "^2.29.1",