From 670cc895dd533e91647a811ef7407ea18968d156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Y=C4=B1lmaz?= Date: Sat, 18 May 2024 12:55:56 +0200 Subject: [PATCH 1/2] =?UTF-8?q?feat(locale):=20=F0=9F=8E=B8=20add=20dateRa?= =?UTF-8?q?nge=20pipe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementation of the Intl.DateTimeFormat.prototype.formatRange() method BREAKING CHANGE: ๐Ÿงจ addition of ES2021.Intl into the typescript configuration โœ… Closes: #763 --- .../src/app/locale/locale.component.html | 199 ++++++++++------- .../src/app/locale/locale.component.ts | 1 + apps/transloco-playground/tsconfig.json | 4 +- libs/transloco-locale/src/index.ts | 4 + libs/transloco-locale/src/lib/helpers.ts | 15 ++ libs/transloco-locale/src/lib/pipes/index.ts | 1 + .../lib/pipes/transloco-date-range.pipe.ts | 50 +++++ .../pipes/transloco-date-range.pipe.spec.ts | 140 ++++++++++++ .../src/lib/transloco-locale.module.ts | 4 +- .../src/lib/transloco-locale.providers.ts | 14 ++ .../src/lib/transloco-locale.service.ts | 27 +++ .../src/lib/transloco-locale.transformers.ts | 17 +- libs/transloco-locale/tsconfig.lib.json | 17 +- .../tsconfig.lib.json | 18 +- .../transloco-preload-langs/tsconfig.lib.json | 17 +- migrations.json | 200 ++++++------------ nx.json | 3 +- package.json | 61 +++--- tsconfig.base.json | 33 ++- tsconfig.json | 5 +- 20 files changed, 561 insertions(+), 269 deletions(-) create mode 100644 libs/transloco-locale/src/lib/pipes/transloco-date-range.pipe.ts create mode 100644 libs/transloco-locale/src/lib/tests/pipes/transloco-date-range.pipe.spec.ts diff --git a/apps/transloco-playground/src/app/locale/locale.component.html b/apps/transloco-playground/src/app/locale/locale.component.html index b14a3a0e0..f796d9180 100644 --- a/apps/transloco-playground/src/app/locale/locale.component.html +++ b/apps/transloco-playground/src/app/locale/locale.component.html @@ -7,82 +7,133 @@

Localization Support for Transloco

href="https://norbertlindenberg.com/2012/12/ecmascript-internationalization-api/index.html" target="_blank" >Internalization api. -

+ >. +

-
Select any locale from the list to see his format:
- +
Select any locale from the list to see his format:
+ -

Date Format

+

Date Format

- + -

Number Format

- +

Date Range Format

-

Currency Format

- + + +

Number Format

+ + +

Currency Format

+ diff --git a/apps/transloco-playground/src/app/locale/locale.component.ts b/apps/transloco-playground/src/app/locale/locale.component.ts index 8de8038fb..691ff8099 100644 --- a/apps/transloco-playground/src/app/locale/locale.component.ts +++ b/apps/transloco-playground/src/app/locale/locale.component.ts @@ -19,6 +19,7 @@ import { }) export default class LocaleComponent { date = new Date(2019, 7, 14, 0, 0, 0, 0); + endDate = new Date(2019, 8, 5, 0, 0, 0, 0); localeList: string[]; constructor( diff --git a/apps/transloco-playground/tsconfig.json b/apps/transloco-playground/tsconfig.json index d3e8c7d98..de2762993 100644 --- a/apps/transloco-playground/tsconfig.json +++ b/apps/transloco-playground/tsconfig.json @@ -15,11 +15,11 @@ "strict": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "target": "es2020" + "target": "es2021" }, "angularCompilerOptions": { "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } -} +} \ No newline at end of file diff --git a/libs/transloco-locale/src/index.ts b/libs/transloco-locale/src/index.ts index 031e6fc4a..04c45fcb3 100644 --- a/libs/transloco-locale/src/index.ts +++ b/libs/transloco-locale/src/index.ts @@ -9,8 +9,10 @@ export { export { TranslocoLocaleModule } from './lib/transloco-locale.module'; export { TRANSLOCO_DATE_TRANSFORMER, + TRANSLOCO_DATE_RANGE_TRANSFORMER, TRANSLOCO_NUMBER_TRANSFORMER, TranslocoDateTransformer, + TranslocoDateRangeTransformer, TranslocoNumberTransformer, DefaultDateTransformer, DefaultNumberTransformer, @@ -19,6 +21,7 @@ export { provideTranslocoLocaleLangMapping, provideTranslocoLocaleCurrencyMapping, provideTranslocoDateTransformer, + provideTranslocoDateRangeTransformer, provideTranslocoDefaultCurrency, provideTranslocoLocale, provideTranslocoNumberTransformer, @@ -29,6 +32,7 @@ export * from './lib/transloco-locale.types'; export { TranslocoCurrencyPipe, TranslocoDatePipe, + TranslocoDateRangePipe, TranslocoDecimalPipe, TranslocoPercentPipe, BaseLocalePipe, diff --git a/libs/transloco-locale/src/lib/helpers.ts b/libs/transloco-locale/src/lib/helpers.ts index 2f545ec7f..bba85aa90 100644 --- a/libs/transloco-locale/src/lib/helpers.ts +++ b/libs/transloco-locale/src/lib/helpers.ts @@ -43,6 +43,21 @@ export function localizeDate( return ''; } +export function localizeDateRange( + startDate: Date, + endDate: Date, + locale: Locale, + options: DateFormatOptions, +): string { + if (isDate(startDate) && isDate(endDate)) { + return new Intl.DateTimeFormat(locale, options as any).formatRange( + startDate, + endDate, + ); + } + return ''; +} + export function isDate(value: any): boolean { return value instanceof Date && !isNaN(value); } diff --git a/libs/transloco-locale/src/lib/pipes/index.ts b/libs/transloco-locale/src/lib/pipes/index.ts index aa069521f..aa0c1ae6e 100644 --- a/libs/transloco-locale/src/lib/pipes/index.ts +++ b/libs/transloco-locale/src/lib/pipes/index.ts @@ -1,5 +1,6 @@ export { TranslocoCurrencyPipe } from './transloco-currency.pipe'; export { TranslocoDatePipe } from './transloco-date.pipe'; +export { TranslocoDateRangePipe } from './transloco-date-range.pipe'; export { TranslocoDecimalPipe } from './transloco-decimal.pipe'; export { BaseLocalePipe } from './base-locale.pipe'; export { TranslocoPercentPipe } from './transloco-percent.pipe'; diff --git a/libs/transloco-locale/src/lib/pipes/transloco-date-range.pipe.ts b/libs/transloco-locale/src/lib/pipes/transloco-date-range.pipe.ts new file mode 100644 index 000000000..b1287b579 --- /dev/null +++ b/libs/transloco-locale/src/lib/pipes/transloco-date-range.pipe.ts @@ -0,0 +1,50 @@ +import { inject, Pipe, PipeTransform } from '@angular/core'; +import { isNil } from '@jsverse/transloco'; + +import { toDate } from "../helpers"; +import { getDefaultOptions } from "../shared"; +import { TRANSLOCO_LOCALE_CONFIG } from "../transloco-locale.config"; +import { Locale, DateFormatOptions, LocaleConfig, ValidDate } from "../transloco-locale.types"; +import { BaseLocalePipe } from "./base-locale.pipe"; + +@Pipe({ + name: 'translocoDateRange', + pure: false, + standalone: true, +}) +export class TranslocoDateRangePipe + extends BaseLocalePipe + implements PipeTransform { + private localeConfig: LocaleConfig = inject(TRANSLOCO_LOCALE_CONFIG); + + /** + * Transform two dates into the locale's date range format. + * + * The date expression: a `Date` object, a number + * (milliseconds since UTC epoch), or an ISO string (https://www.w3.org/TR/NOTE-datetime). + * + * @example + * + * startDate | translocoDateRange: endDate : {} : en-US // 9/10โ€“10/10/2019 + * startDate | translocoDate: endDate : { dateStyle: 'medium', timeStyle: 'medium' } : en-US // Sep 10, 2019, 10:46:12 PM โ€“ Oct 10, 2019, 10:46:12 PM + * '2019-02-08' | translocoDate: '2020-03-10' : { dateStyle: 'medium' } // Feb 8 2019 โ€“ Mar 10 2020 + */ + transform( + startDate: ValidDate, + endDate: ValidDate, + options: DateFormatOptions = {}, + locale?: Locale, + ) { + if (isNil(startDate)) return ''; + if (isNil(endDate)) { + // @TODO Fallback to TranslocoDatePipe; + return '' + }; + locale = this.getLocale(locale); + + return this.localeService.localizeDateRange(startDate, endDate, locale, { + ...getDefaultOptions(locale, 'date', this.localeConfig), + ...options, + }); + } +} diff --git a/libs/transloco-locale/src/lib/tests/pipes/transloco-date-range.pipe.spec.ts b/libs/transloco-locale/src/lib/tests/pipes/transloco-date-range.pipe.spec.ts new file mode 100644 index 000000000..527b74bf5 --- /dev/null +++ b/libs/transloco-locale/src/lib/tests/pipes/transloco-date-range.pipe.spec.ts @@ -0,0 +1,140 @@ +import { SpectatorPipe } from '@ngneat/spectator'; + +import { TranslocoDateRangePipe } from '../../pipes'; +import { + LOCALE_CONFIG_MOCK, + provideTranslocoLocaleConfigMock, + provideTranslocoServiceMock, +} from '../mocks'; +import { createLocalePipeFactory } from '../utils'; + +describe('TranslocoDateRangePipe', () => { + let intlSpy: jasmine.Spy<(typeof Intl)['DateTimeFormat']>; + let spectator: SpectatorPipe; + const pipeFactory = createLocalePipeFactory(TranslocoDateRangePipe); + + const startDate = new Date(2019, 9, 7, 12, 0, 0); + const endDate = new Date(2020, 4, 15, 16, 0, 0); + + function getIntlCallArgs() { + const [locale, options] = intlSpy.calls.argsFor(0); + + return [locale!, options!] as const; + } + + beforeEach(() => { + intlSpy = spyOn(Intl, 'DateTimeFormat').and.callThrough(); + }); + + it('should transform date to locale formatted date', () => { + spectator = pipeFactory(`{{ startDate | translocoDateRange:endDate }}`, { + hostProps: { + startDate: startDate, + endDate: endDate, + }, + }); + expect(spectator.element).toHaveText('9/7/2019 โ€“ 4/15/2020'); + }); + + it('should consider a given format over the current locale', () => { + spectator = pipeFactory(`{{ startDate | translocoDateRange:endDate:config }}`, { + hostProps: { + startDate: startDate, + config: { dateStyle: 'medium', timeStyle: 'medium' }, + }, + }); + const [, { dateStyle, timeStyle }] = getIntlCallArgs(); + expect(dateStyle).toEqual('medium'); + expect(timeStyle).toEqual('medium'); + }); + + it('should consider a global date config', () => { + spectator = pipeFactory(`{{ startDate | translocoDateRange:endDate }}`, { + hostProps: { + startDate: startDate, + }, + providers: [provideTranslocoLocaleConfigMock(LOCALE_CONFIG_MOCK)], + }); + const [, { dateStyle, timeStyle }] = getIntlCallArgs(); + expect(dateStyle).toEqual('medium'); + expect(timeStyle).toEqual('medium'); + }); + + it('should consider a locale config over global', () => { + spectator = pipeFactory(`{{ startDate | translocoDateRange:endDate }}`, { + hostProps: { + startDate: startDate, + }, + providers: [ + provideTranslocoLocaleConfigMock(LOCALE_CONFIG_MOCK), + provideTranslocoServiceMock('es-ES'), + ], + }); + const [locale, { dateStyle, timeStyle }] = getIntlCallArgs(); + expect(locale).toEqual('es-ES'); + expect(dateStyle).toEqual('long'); + expect(timeStyle).toEqual('long'); + }); + + it('should consider a given config over the global config', () => { + spectator = pipeFactory(`{{ startDate | translocoDateRange:endDate:config }}`, { + hostProps: { + startDate: startDate, + config: { dateStyle: 'full' }, + }, + providers: [provideTranslocoLocaleConfigMock(LOCALE_CONFIG_MOCK)], + }); + const [, { dateStyle, timeStyle }] = getIntlCallArgs(); + expect(dateStyle).toEqual('full'); + expect(timeStyle).toEqual('medium'); + }); + + describe('None date values', () => { + it('should handle null', () => { + spectator = pipeFactory(`{{ null | translocoDateRange:null }}`); + expect(spectator.element).toHaveText(''); + }); + it('should handle {}', () => { + spectator = pipeFactory(`{{ {} | translocoDateRange:{} }}`); + expect(spectator.element).toHaveText(''); + }); + it('should handle none number string', () => { + spectator = pipeFactory(`{{ 'none number string' | translocoDateRange:'none number string' }}`); + expect(spectator.element).toHaveText(''); + }); + }); + + it('should transform number to date', () => { + spectator = pipeFactory(`{{ startDate | translocoDateRange:endDate:config }}`, { + hostProps: { + startDate: 0, + endDate: 1000000000, + config: { timeZone: 'UTC' }, + }, + }); + expect(spectator.element).toHaveText('1/1/1970 โ€“ 9/9/2001'); + }); + + it('should transform string to date', () => { + spectator = pipeFactory(`{{ startDate | translocoDateRange:config }}`, { + hostProps: { + startDate: '2019-02-08', + endDate: '2020-05-15', + }, + }); + expect(spectator.element).toHaveText('2/8/2019โ€“5/15/2020'); + }); + + it('should transform an ISO 8601 string to date', () => { + spectator = pipeFactory(`{{ startDate | translocoDateRange:config:locale }}`, { + hostProps: { + startDate: '2019-09-12T19:51:33Z', + endDate: '2019-10-12T19:51:33Z', + config: { timeZone: 'UTC' }, + locale: 'en-US', + }, + providers: [provideTranslocoLocaleConfigMock(LOCALE_CONFIG_MOCK)], + }); + expect(spectator.element).toHaveText('Sep 12, 2019, 7:51:33 PM โ€“ Oct 12, 2019, 7:51:33 PM'); + }); +}); diff --git a/libs/transloco-locale/src/lib/transloco-locale.module.ts b/libs/transloco-locale/src/lib/transloco-locale.module.ts index 2a0891c5b..a62275c57 100644 --- a/libs/transloco-locale/src/lib/transloco-locale.module.ts +++ b/libs/transloco-locale/src/lib/transloco-locale.module.ts @@ -3,6 +3,7 @@ import { NgModule } from '@angular/core'; import { TranslocoCurrencyPipe, TranslocoDatePipe, + TranslocoDateRangePipe, TranslocoDecimalPipe, TranslocoPercentPipe, } from './pipes'; @@ -10,6 +11,7 @@ import { const decl = [ TranslocoCurrencyPipe, TranslocoDatePipe, + TranslocoDateRangePipe, TranslocoDecimalPipe, TranslocoPercentPipe, ]; @@ -18,4 +20,4 @@ const decl = [ imports: decl, exports: decl, }) -export class TranslocoLocaleModule {} +export class TranslocoLocaleModule { } diff --git a/libs/transloco-locale/src/lib/transloco-locale.providers.ts b/libs/transloco-locale/src/lib/transloco-locale.providers.ts index b9229d251..9c2a04fb9 100644 --- a/libs/transloco-locale/src/lib/transloco-locale.providers.ts +++ b/libs/transloco-locale/src/lib/transloco-locale.providers.ts @@ -18,11 +18,14 @@ import { } from './transloco-locale.config'; import { DefaultDateTransformer, + DefaultDateRangeTransformer, DefaultNumberTransformer, TRANSLOCO_DATE_TRANSFORMER, + TRANSLOCO_DATE_RANGE_TRANSFORMER, TRANSLOCO_NUMBER_TRANSFORMER, TranslocoDateTransformer, TranslocoNumberTransformer, + TranslocoDateRangeTransformer, } from './transloco-locale.transformers'; export function provideTranslocoLocale(config?: TranslocoLocaleConfig) { @@ -38,6 +41,7 @@ export function provideTranslocoLocale(config?: TranslocoLocaleConfig) { provideTranslocoLocaleLangMapping(merged.langToLocaleMapping), provideTranslocoLocaleCurrencyMapping(merged.localeToCurrencyMapping), provideTranslocoDateTransformer(DefaultDateTransformer), + provideTranslocoDateRangeTransformer(DefaultDateRangeTransformer), provideTranslocoNumberTransformer(DefaultNumberTransformer), ]; } @@ -101,6 +105,16 @@ export function provideTranslocoDateTransformer( }, ]); } +export function provideTranslocoDateRangeTransformer( + transformer: Type +) { + return makeEnvironmentProviders([ + { + provide: TRANSLOCO_DATE_RANGE_TRANSFORMER, + useClass: transformer, + }, + ]); +} export function provideTranslocoNumberTransformer( transformer: Type diff --git a/libs/transloco-locale/src/lib/transloco-locale.service.ts b/libs/transloco-locale/src/lib/transloco-locale.service.ts index f71a8fad9..20df15757 100644 --- a/libs/transloco-locale/src/lib/transloco-locale.service.ts +++ b/libs/transloco-locale/src/lib/transloco-locale.service.ts @@ -13,6 +13,7 @@ import { TRANSLOCO_LOCALE_LANG_MAPPING, } from './transloco-locale.config'; import { + TRANSLOCO_DATE_RANGE_TRANSFORMER, TRANSLOCO_DATE_TRANSFORMER, TRANSLOCO_NUMBER_TRANSFORMER, } from './transloco-locale.transformers'; @@ -35,6 +36,7 @@ export class TranslocoLocaleService implements OnDestroy { private localeCurrencyMapping = inject(TRANSLOCO_LOCALE_CURRENCY_MAPPING); private numberTransformer = inject(TRANSLOCO_NUMBER_TRANSFORMER); private dateTransformer = inject(TRANSLOCO_DATE_TRANSFORMER); + private dateRangeTransformer = inject(TRANSLOCO_DATE_RANGE_TRANSFORMER); private localeConfig: LocaleConfig = inject(TRANSLOCO_LOCALE_CONFIG); private _locale = @@ -110,6 +112,31 @@ export class TranslocoLocaleService implements OnDestroy { return this.dateTransformer.transform(toDate(date), locale, resolved); } + /** + /** + * Transform two dates into the locale's date range format. + * + * The date expression: a `Date` object, a number + * (milliseconds since UTC epoch), or an ISO string (https://www.w3.org/TR/NOTE-datetime). + * + * @example + * + * startDate | translocoDateRange: endDate : {} : en-US // 9/10โ€“10/10/2019 + * startDate | translocoDate: endDate : { dateStyle: 'medium', timeStyle: 'medium' } : en-US // Sep 10, 2019, 10:46:12 PM โ€“ Oct 10, 2019, 10:46:12 PM + * '2019-02-08' | translocoDate: '2020-03-10' : { dateStyle: 'medium' } // Feb 8 2019 โ€“ Mar 10 2020 + */ + localizeDateRange( + startDate: ValidDate, + endDate: ValidDate, + locale: Locale = this.getLocale(), + options: DateFormatOptions = {} + ): string { + const resolved = + options ?? getDefaultOptions(locale, 'date', this.localeConfig); + + return this.dateRangeTransformer.transform(toDate(startDate), toDate(endDate), locale, resolved); + } + /** * Transform a number into the locale's number format according to the number type. * diff --git a/libs/transloco-locale/src/lib/transloco-locale.transformers.ts b/libs/transloco-locale/src/lib/transloco-locale.transformers.ts index fb9124206..879ff6fc3 100644 --- a/libs/transloco-locale/src/lib/transloco-locale.transformers.ts +++ b/libs/transloco-locale/src/lib/transloco-locale.transformers.ts @@ -1,6 +1,6 @@ import { InjectionToken } from '@angular/core'; -import { localizeNumber, localizeDate } from './helpers'; +import { localizeNumber, localizeDate, localizeDateRange, } from './helpers'; import { Locale, DateFormatOptions, @@ -10,6 +10,9 @@ import { export interface TranslocoDateTransformer { transform(date: Date, locale: Locale, options: DateFormatOptions): string; } +export interface TranslocoDateRangeTransformer { + transform(startDate: Date, endDate: Date, locale: Locale, options: DateFormatOptions): string; +} export interface TranslocoNumberTransformer { transform( value: number | string, @@ -21,6 +24,8 @@ export interface TranslocoNumberTransformer { export const TRANSLOCO_DATE_TRANSFORMER = new InjectionToken('TRANSLOCO_DATE_TRANSFORMER'); +export const TRANSLOCO_DATE_RANGE_TRANSFORMER = + new InjectionToken('TRANSLOCO_DATE_TRANSFORMER'); export const TRANSLOCO_NUMBER_TRANSFORMER = new InjectionToken( 'TRANSLOCO_NUMBER_TRANSFORMER' @@ -35,6 +40,16 @@ export class DefaultDateTransformer implements TranslocoDateTransformer { return localizeDate(date, locale, options); } } +export class DefaultDateRangeTransformer implements TranslocoDateRangeTransformer { + public transform( + startDate: Date, + endDate: Date, + locale: Locale, + options: DateFormatOptions + ): string { + return localizeDateRange(startDate, endDate, locale, options); + } +} export class DefaultNumberTransformer implements TranslocoNumberTransformer { public transform( value: number | string, diff --git a/libs/transloco-locale/tsconfig.lib.json b/libs/transloco-locale/tsconfig.lib.json index 674998f08..f8b8bc07e 100644 --- a/libs/transloco-locale/tsconfig.lib.json +++ b/libs/transloco-locale/tsconfig.lib.json @@ -7,8 +7,17 @@ "declarationMap": true, "inlineSources": true, "types": [], - "lib": ["dom", "ES2020"] + "lib": [ + "dom", + "ES2020", + "ES2021.Intl" + ] }, - "exclude": ["src/test-setup.ts", "**/*.spec.ts"], - "include": ["**/*.ts"] -} + "exclude": [ + "src/test-setup.ts", + "**/*.spec.ts" + ], + "include": [ + "**/*.ts" + ] +} \ No newline at end of file diff --git a/libs/transloco-persist-translations/tsconfig.lib.json b/libs/transloco-persist-translations/tsconfig.lib.json index 18b202a81..ebaedcdc1 100644 --- a/libs/transloco-persist-translations/tsconfig.lib.json +++ b/libs/transloco-persist-translations/tsconfig.lib.json @@ -7,8 +7,18 @@ "declarationMap": true, "inlineSources": true, "types": [], - "lib": ["dom", "es2020"] + "lib": [ + "dom", + "es2020", + "ES2021.Intl" + ] }, - "exclude": ["src/test-setup.ts", "**/*.spec.ts", "src/lib/tests/mocks.ts"], - "include": ["**/*.ts"] -} + "exclude": [ + "src/test-setup.ts", + "**/*.spec.ts", + "src/lib/tests/mocks.ts" + ], + "include": [ + "**/*.ts" + ] +} \ No newline at end of file diff --git a/libs/transloco-preload-langs/tsconfig.lib.json b/libs/transloco-preload-langs/tsconfig.lib.json index 82243b44d..4c820dbad 100644 --- a/libs/transloco-preload-langs/tsconfig.lib.json +++ b/libs/transloco-preload-langs/tsconfig.lib.json @@ -7,8 +7,17 @@ "declarationMap": true, "inlineSources": true, "types": [], - "lib": ["dom", "es2020"] + "lib": [ + "dom", + "es2020", + "ES2021.Intl" + ] }, - "exclude": ["src/test-setup.ts", "**/*.spec.ts"], - "include": ["**/*.ts"] -} + "exclude": [ + "src/test-setup.ts", + "**/*.spec.ts" + ], + "include": [ + "**/*.ts" + ] +} \ No newline at end of file diff --git a/migrations.json b/migrations.json index 03de1a42c..27081e19d 100644 --- a/migrations.json +++ b/migrations.json @@ -2,196 +2,120 @@ "migrations": [ { "cli": "nx", - "version": "16.8.0-beta.3", - "description": "Escape $ in env variables", - "implementation": "./src/migrations/update-16-8-0/escape-dollar-sign-env-variables", + "version": "17.3.0-beta.6", + "description": "Updates the nx wrapper.", + "implementation": "./src/migrations/update-17-3-0/update-nxw", "package": "nx", - "name": "16.8.0-escape-dollar-sign-env" + "name": "17.3.0-update-nx-wrapper" }, { "cli": "nx", - "version": "17.0.0-beta.1", - "description": "Updates the default cache directory to .nx/cache", - "implementation": "./src/migrations/update-17-0-0/move-cache-directory", + "version": "18.0.0-beta.2", + "description": "Updates nx.json to disabled adding plugins when generating projects in an existing Nx workspace", + "implementation": "./src/migrations/update-18-0-0/disable-crystal-for-existing-workspaces", + "x-repair-skip": true, "package": "nx", - "name": "17.0.0-move-cache-directory" + "name": "18.0.0-disable-adding-plugins-for-existing-workspaces" }, { - "cli": "nx", - "version": "17.0.0-beta.3", - "description": "Use minimal config for tasksRunnerOptions", - "implementation": "./src/migrations/update-17-0-0/use-minimal-config-for-tasks-runner-options", - "package": "nx", - "name": "17.0.0-use-minimal-config-for-tasks-runner-options" - }, - { - "version": "17.0.0-rc.1", - "description": "Migration for v17.0.0-rc.1", - "implementation": "./src/migrations/update-17-0-0/rm-default-collection-npm-scope", + "version": "18.1.0-beta.3", + "description": "Moves affected.defaultBase to defaultBase in `nx.json`", + "implementation": "./src/migrations/update-17-2-0/move-default-base", "package": "nx", - "name": "rm-default-collection-npm-scope" - }, - { - "version": "17.1.0-beta.2", - "description": "Move jest executor options to nx.json targetDefaults", - "implementation": "./src/migrations/update-17-1-0/move-options-to-target-defaults", - "package": "@nx/jest", - "name": "move-options-to-target-defaults" + "name": "move-default-base-to-nx-json-root" }, { "cli": "nx", - "version": "17-2-6-beta.1", - "description": "Rename workspace rules from @nx/workspace/name to @nx/workspace-name", - "implementation": "./src/migrations/update-17-2-6-rename-workspace-rules/rename-workspace-rules", - "package": "@nx/eslint-plugin", - "name": "update-17-2-6-rename-workspace-rules" - }, - { - "cli": "nx", - "version": "16.8.2-beta.0", - "description": "Remove invalid options (strict, noInterop) for ES6 type modules.", - "factory": "./src/migrations/update-16-8-2/update-swcrc", - "package": "@nx/js", - "name": "16-8-2-update-swcrc" - }, - { - "cli": "nx", - "version": "17.0.2", - "description": "Remove deprecated build options", - "implementation": "./src/migrations/update-17-0-0/remove-deprecated-build-options", - "package": "@nx/js", - "name": "update-17-0-0-remove-deprecated-build-options" - }, - { - "cli": "nx", - "version": "16.8.0-beta.4", - "description": "Update to Cypress v13. Most noteable change is video recording is off by default. This migration will only update if the workspace is already on Cypress v12. https://docs.cypress.io/guides/references/migration-guide#Migrating-to-Cypress-130", - "implementation": "./src/migrations/update-16-8-0/cypress-13", - "package": "@nx/cypress", - "name": "update-16-8-0-cypress-13" - }, - { - "cli": "nx", - "version": "16.7.0-beta.6", + "version": "17.3.0-beta.10", "requires": { - "@angular/core": ">=16.2.0" + "@angular/core": ">=17.1.0" }, - "description": "Update the @angular/cli package version to ~16.2.0.", - "factory": "./src/migrations/update-16-7-0/update-angular-cli", + "description": "Update the @angular/cli package version to ~17.1.0.", + "factory": "./src/migrations/update-17-3-0/update-angular-cli", "package": "@nx/angular", - "name": "update-angular-cli-version-16-2-0" + "name": "update-angular-cli-version-17-1-0" }, { "cli": "nx", - "version": "17.1.0-beta.5", + "version": "17.3.0-beta.10", "requires": { - "@angular/core": ">=17.0.0" + "@angular/core": ">=17.1.0" }, - "description": "Update the @angular/cli package version to ~17.0.0.", - "factory": "./src/migrations/update-17-1-0/update-angular-cli", + "description": "Add 'browser-sync' as dev dependency when '@angular-devkit/build-angular:ssr-dev-server' or '@nx/angular:module-federation-dev-ssr' is used.", + "factory": "./src/migrations/update-17-3-0/add-browser-sync-dependency", "package": "@nx/angular", - "name": "update-angular-cli-version-17-0-0" + "name": "add-browser-sync-dependency" }, { "cli": "nx", - "version": "17.1.0-beta.5", + "version": "17.3.0-beta.10", "requires": { - "@angular/core": ">=17.0.0" + "@angular/core": ">=17.1.0" }, - "description": "Rename 'browserTarget' to 'buildTarget'.", - "factory": "./src/migrations/update-17-1-0/browser-target-to-build-target", + "description": "Add 'autoprefixer' as dev dependency when '@nx/angular:ng-packagr-lite' or '@nx/angular:package` is used.", + "factory": "./src/migrations/update-17-3-0/add-autoprefixer-dependency", "package": "@nx/angular", - "name": "rename-browser-target-to-build-target" + "name": "add-autoprefixer-dependency" }, { "cli": "nx", - "version": "17.1.0-beta.5", - "requires": { - "@angular/core": ">=17.0.0" - }, - "description": "Replace usages of '@nguniversal/builders' with '@angular-devkit/build-angular'.", - "factory": "./src/migrations/update-17-1-0/replace-nguniversal-builders", + "version": "18.0.0-beta.0", + "description": "Add NX_MF_DEV_SERVER_STATIC_REMOTES to inputs for task hashing when '@nx/angular:webpack-browser' is used for Module Federation.", + "factory": "./src/migrations/update-18-0-0/add-mf-env-var-to-target-defaults", "package": "@nx/angular", - "name": "replace-nguniversal-builders" + "name": "add-module-federation-env-var-to-target-defaults" }, { "cli": "nx", - "version": "17.1.0-beta.5", + "version": "18.1.0-beta.1", "requires": { - "@angular/core": ">=17.0.0" + "@angular/core": ">=17.2.0" }, - "description": "Replace usages of '@nguniversal/' packages with '@angular/ssr'.", - "factory": "./src/migrations/update-17-1-0/replace-nguniversal-engines", + "description": "Update the @angular/cli package version to ~17.2.0.", + "factory": "./src/migrations/update-18-1-0/update-angular-cli", "package": "@nx/angular", - "name": "replace-nguniversal-engines" + "name": "update-angular-cli-version-17-2-0" }, { "cli": "nx", - "version": "17.1.0-beta.5", - "requires": { - "@angular/core": ">=17.0.0" - }, - "description": "Replace the deep imports from 'zone.js/dist/zone' and 'zone.js/dist/zone-testing' with 'zone.js' and 'zone.js/testing'.", - "factory": "./src/migrations/update-17-1-0/update-zone-js-deep-import", + "version": "18.1.1-beta.0", + "description": "Ensure targetDefaults inputs for task hashing when '@nx/angular:webpack-browser' is used are correct for Module Federation.", + "factory": "./src/migrations/update-18-1-1/fix-target-defaults-inputs", "package": "@nx/angular", - "name": "update-zone-js-deep-import" + "name": "fix-target-defaults-for-webpack-browser" }, { "cli": "nx", - "version": "17.2.0-beta.2", - "description": "Rename '@nx/angular:webpack-dev-server' executor to '@nx/angular:dev-server'", - "factory": "./src/migrations/update-17-2-0/rename-webpack-dev-server", + "version": "18.2.0-beta.0", + "requires": { + "@angular/core": ">=17.3.0" + }, + "description": "Update the @angular/cli package version to ~17.3.0.", + "factory": "./src/migrations/update-18-2-0/update-angular-cli", "package": "@nx/angular", - "name": "rename-webpack-dev-server-executor" - }, - { - "version": "16.8.0", - "description": "update-16-8-0-add-ignored-files", - "implementation": "./src/migrations/update-16-8-0-add-ignored-files/update-16-8-0-add-ignored-files", - "package": "@nx/eslint", - "name": "update-16-8-0-add-ignored-files" - }, - { - "version": "17.0.0-beta.7", - "description": "update-17-0-0-rename-to-eslint", - "implementation": "./src/migrations/update-17-0-0-rename-to-eslint/update-17-0-0-rename-to-eslint", - "package": "@nx/eslint", - "name": "update-17-0-0-rename-to-eslint" + "name": "update-angular-cli-version-17-3-0" }, { - "version": "17.1.0-beta.1", - "description": "Updates for @typescript-utils/utils v6.9.1+", - "implementation": "./src/migrations/update-17-1-0/update-typescript-eslint", + "version": "17.2.9", + "description": "Move executor options to target defaults", + "implementation": "./src/migrations/update-17-2-9/move-options-to-target-defaults", "package": "@nx/eslint", - "name": "update-typescript-eslint" - }, - { - "version": "17.2.0-beta.0", - "description": "Simplify eslintFilePatterns", - "implementation": "./src/migrations/update-17-2-0/simplify-eslint-patterns", - "package": "@nx/eslint", - "name": "simplify-eslint-patterns" - }, - { - "version": "17.0.0", - "description": "Angular v17 introduces a new control flow syntax that uses the @ and } characters. This migration replaces the existing usages with their corresponding HTML entities.", - "factory": "./migrations/block-template-entities/bundle", - "package": "@angular/core", - "name": "block-template-entities" + "name": "move-options-to-target-defaults" }, { - "version": "17.0.0", - "description": "CompilerOption.useJit and CompilerOption.missingTranslation are unused under Ivy. This migration removes their usage", - "factory": "./migrations/compiler-options/bundle", - "package": "@angular/core", - "name": "migration-v17-compiler-options" + "cli": "nx", + "version": "18.1.0-beta.3", + "description": "Update to Cypress ^13.6.6 if the workspace is using Cypress v13 to ensure workspaces don't use v13.6.5 which has an issue when verifying Cypress.", + "implementation": "./src/migrations/update-18-1-0/update-cypress-version-13-6-6", + "package": "@nx/cypress", + "name": "update-cypress-version-13-6-6" }, { - "version": "17.0.0", - "description": "Updates `TransferState`, `makeStateKey`, `StateKey` imports from `@angular/platform-browser` to `@angular/core`.", - "factory": "./migrations/transfer-state/bundle", + "version": "17.3.0", + "description": "Updates two-way bindings that have an invalid expression to use the longform expression instead.", + "factory": "./migrations/invalid-two-way-bindings/bundle", "package": "@angular/core", - "name": "migration-transfer-state" + "name": "invalid-two-way-bindings" } ] } diff --git a/nx.json b/nx.json index 56ec93654..b887ab42b 100644 --- a/nx.json +++ b/nx.json @@ -70,5 +70,6 @@ "!{projectRoot}/src/test-setup.[jt]s" ] }, - "parallel": 1 + "parallel": 1, + "nxCloudAccessToken": "Y2E2ZGVmZDQtOTY5Ni00YWYxLTkyOWUtNGViZmU2N2EyNjFifHJlYWQtd3JpdGU=" } diff --git a/package.json b/package.json index 5dc4b38d0..d6339b885 100644 --- a/package.json +++ b/package.json @@ -35,14 +35,14 @@ "pre-commit": "node scripts/pre-commit.js && lint-staged --allow-empty" }, "dependencies": { - "@angular/animations": "17.0.9", - "@angular/common": "17.0.9", - "@angular/compiler": "17.0.9", - "@angular/core": "17.0.9", - "@angular/forms": "17.0.9", - "@angular/platform-browser": "17.0.9", - "@angular/platform-browser-dynamic": "17.0.9", - "@angular/router": "17.0.9", + "@angular/animations": "17.3.9", + "@angular/common": "17.3.9", + "@angular/compiler": "17.3.9", + "@angular/core": "17.3.9", + "@angular/forms": "17.3.9", + "@angular/platform-browser": "17.3.9", + "@angular/platform-browser-dynamic": "17.3.9", + "@angular/router": "17.3.9", "@messageformat/core": "3.0.0", "bootstrap": "5.3.1", "chalk": "4.1.2", @@ -57,38 +57,38 @@ "replace-in-file": "^7.0.1", "rxjs": "7.8.0", "tslib": "2.3.1", - "zone.js": "0.14.3" + "zone.js": "0.14.6" }, "devDependencies": { - "@angular-devkit/build-angular": "17.0.9", - "@angular-eslint/eslint-plugin": "17.0.1", - "@angular-eslint/eslint-plugin-template": "17.0.1", - "@angular-eslint/template-parser": "17.0.1", + "@angular-devkit/build-angular": "17.3.7", + "@angular-eslint/eslint-plugin": "17.3.0", + "@angular-eslint/eslint-plugin-template": "17.3.0", + "@angular-eslint/template-parser": "17.3.0", "@angular/cli": "~17.0.0", - "@angular/compiler-cli": "17.0.9", - "@angular/language-service": "17.0.9", + "@angular/compiler-cli": "17.3.9", + "@angular/language-service": "17.3.9", "@commitlint/cli": "12.1.4", "@commitlint/config-conventional": "12.1.4", "@jscutlery/semver": "3.1.0", "@ngneat/spectator": "15.0.1", - "@nx/angular": "17.2.8", - "@nx/cypress": "17.2.8", - "@nx/eslint-plugin": "17.2.8", - "@nx/jest": "17.2.8", - "@nx/js": "17.2.8", - "@nx/workspace": "17.2.8", + "@nx/angular": "19.0.4", + "@nx/cypress": "19.0.4", + "@nx/eslint-plugin": "19.0.4", + "@nx/jest": "19.0.4", + "@nx/js": "19.0.4", + "@nx/workspace": "19.0.4", "@types/command-line-args": "5.2.0", "@types/find-duplicated-property-keys": "1.1.3", "@types/fs-extra": "9.0.12", "@types/jasmine": "4.0.3", "@types/jest": "29.5.0", - "@types/node": "18.16.9", - "@typescript-eslint/eslint-plugin": "6.19.1", - "@typescript-eslint/parser": "6.19.1", + "@types/node": "^18.16.9", + "@typescript-eslint/eslint-plugin": "7.9.0", + "@typescript-eslint/parser": "7.9.0", "cheerio": "^1.0.0-rc.12", "cypress": "^13.0.0", "dotenv": "10.0.0", - "eslint": "8.48.0", + "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-cypress": "2.15.1", @@ -99,7 +99,7 @@ "jasmine-spec-reporter": "7.0.0", "jest": "29.5.0", "jest-environment-jsdom": "29.5.0", - "jest-preset-angular": "13.1.6", + "jest-preset-angular": "14.0.4", "karma": "6.4.1", "karma-chrome-launcher": "3.1.0", "karma-coverage": "~2.2.0", @@ -107,8 +107,8 @@ "karma-jasmine": "5.1.0", "karma-jasmine-html-reporter": "2.0.0", "lint-staged": "13.2.3", - "ng-packagr": "17.0.3", - "nx": "17.2.8", + "ng-packagr": "17.3.0", + "nx": "19.0.4", "postcss": "8.4.21", "postcss-import": "14.1.0", "postcss-preset-env": "8.2.0", @@ -117,9 +117,9 @@ "ts-jest": "29.1.0", "ts-mocks": "3.0.1", "ts-node": "10.9.1", - "typescript": "5.2.2", + "typescript": "5.4.5", "verdaccio": "^5.0.4", - "@nx/eslint": "17.2.8" + "@nx/eslint": "19.0.4" }, "config": { "commitizen": { @@ -130,3 +130,4 @@ "includedScripts": [] } } + diff --git a/tsconfig.base.json b/tsconfig.base.json index 6f6d8c960..000d827f2 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -10,17 +10,27 @@ "importHelpers": true, "target": "ES2022", "module": "esnext", - "lib": ["es2020", "dom"], + "lib": [ + "es2020", + "dom", + "ES2021.Intl" + ], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", "paths": { - "@jsverse/transloco": ["libs/transloco/src/index.ts"], - "@jsverse/transloco-locale": ["libs/transloco-locale/src/index.ts"], + "@jsverse/transloco": [ + "libs/transloco/src/index.ts" + ], + "@jsverse/transloco-locale": [ + "libs/transloco-locale/src/index.ts" + ], "@jsverse/transloco-messageformat": [ "libs/transloco-messageformat/src/index.ts" ], - "@jsverse/transloco-optimize": ["libs/transloco-optimize/src/index.ts"], + "@jsverse/transloco-optimize": [ + "libs/transloco-optimize/src/index.ts" + ], "@jsverse/transloco-persist-lang": [ "libs/transloco-persist-lang/src/index.ts" ], @@ -36,9 +46,16 @@ "@jsverse/transloco-scoped-libs": [ "libs/transloco-scoped-libs/src/index.ts" ], - "@jsverse/transloco-utils": ["libs/transloco-utils/src/index.ts"], - "@jsverse/transloco-validator": ["libs/transloco-validator/src/index.ts"] + "@jsverse/transloco-utils": [ + "libs/transloco-utils/src/index.ts" + ], + "@jsverse/transloco-validator": [ + "libs/transloco-validator/src/index.ts" + ] } }, - "exclude": ["node_modules", "tmp"] -} + "exclude": [ + "node_modules", + "tmp" + ] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 0cbd8faea..30ce5c534 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,8 +19,9 @@ ], "lib": [ "es2018", - "dom" + "dom", + "ES2021.Intl" ], "useDefineForClassFields": false } -} +} \ No newline at end of file From 9ec00efb0b6aec76711e34acb6eb6d0747f59f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Y=C4=B1lmaz?= Date: Sat, 14 Sep 2024 16:47:38 +0200 Subject: [PATCH 2/2] feat: update transloco-date-range.pipe.ts - feat: fallback to single date translocoDate pipe if no endDate - fix: linting --- .../lib/pipes/transloco-date-range.pipe.ts | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/libs/transloco-locale/src/lib/pipes/transloco-date-range.pipe.ts b/libs/transloco-locale/src/lib/pipes/transloco-date-range.pipe.ts index b1287b579..f2fcfab87 100644 --- a/libs/transloco-locale/src/lib/pipes/transloco-date-range.pipe.ts +++ b/libs/transloco-locale/src/lib/pipes/transloco-date-range.pipe.ts @@ -1,11 +1,17 @@ import { inject, Pipe, PipeTransform } from '@angular/core'; import { isNil } from '@jsverse/transloco'; -import { toDate } from "../helpers"; -import { getDefaultOptions } from "../shared"; -import { TRANSLOCO_LOCALE_CONFIG } from "../transloco-locale.config"; -import { Locale, DateFormatOptions, LocaleConfig, ValidDate } from "../transloco-locale.types"; -import { BaseLocalePipe } from "./base-locale.pipe"; +import { getDefaultOptions } from '../shared'; +import { TRANSLOCO_LOCALE_CONFIG } from '../transloco-locale.config'; +import { + Locale, + DateFormatOptions, + LocaleConfig, + ValidDate, +} from '../transloco-locale.types'; + +import { BaseLocalePipe } from './base-locale.pipe'; +import { TranslocoDatePipe } from './transloco-date.pipe'; @Pipe({ name: 'translocoDateRange', @@ -14,7 +20,8 @@ import { BaseLocalePipe } from "./base-locale.pipe"; }) export class TranslocoDateRangePipe extends BaseLocalePipe - implements PipeTransform { + implements PipeTransform +{ private localeConfig: LocaleConfig = inject(TRANSLOCO_LOCALE_CONFIG); /** @@ -37,9 +44,9 @@ export class TranslocoDateRangePipe ) { if (isNil(startDate)) return ''; if (isNil(endDate)) { - // @TODO Fallback to TranslocoDatePipe; - return '' - }; + return inject(TranslocoDatePipe).transform(startDate, options, locale); + } + locale = this.getLocale(locale); return this.localeService.localizeDateRange(startDate, endDate, locale, {