Browse Source

fix(admin-ui): Improve handling of locale combinations

Michael Bromley 4 years ago
parent
commit
87f9f7817d

+ 22 - 0
packages/admin-ui/src/lib/core/src/shared/pipes/locale-base.pipe.ts

@@ -33,5 +33,27 @@ export abstract class LocaleBasePipe implements OnDestroy, PipeTransform {
         }
     }
 
+    /**
+     * Returns the active locale after attempting to ensure that the locale string
+     * is valid for the Intl API.
+     */
+    protected getActiveLocale(localeOverride?: unknown): string {
+        const locale = typeof localeOverride === 'string' ? localeOverride : this.locale ?? 'en';
+        const hyphenated = locale?.replace(/_/g, '-');
+
+        // Check for a double-region string, containing 2 region codes like
+        // pt-BR-BR, which is invalid. In this case, the second region is used
+        // and the first region discarded. This would only ever be an issue for
+        // those languages where the translation file itself encodes the region,
+        // as in pt_BR & pt_PT.
+        const matches = hyphenated?.match(/^([a-zA-Z_-]+)(-[A-Z][A-Z])(-[A-Z][A-z])$/);
+        if (matches?.length) {
+            const overriddenLocale = matches[1] + matches[3];
+            return overriddenLocale;
+        } else {
+            return hyphenated;
+        }
+    }
+
     abstract transform(value: any, ...args): any;
 }

+ 1 - 1
packages/admin-ui/src/lib/core/src/shared/pipes/locale-currency-name.pipe.ts

@@ -32,7 +32,7 @@ export class LocaleCurrencyNamePipe extends LocaleBasePipe implements PipeTransf
         }
         let name = '';
         let symbol = '';
-        const activeLocale = typeof locale === 'string' ? locale : this.locale ?? 'en';
+        const activeLocale = this.getActiveLocale(locale);
 
         // Awaiting TS types for this API: https://github.com/microsoft/TypeScript/pull/44022/files
         const DisplayNames = (Intl as any).DisplayNames;

+ 1 - 1
packages/admin-ui/src/lib/core/src/shared/pipes/locale-currency.pipe.ts

@@ -28,7 +28,7 @@ export class LocaleCurrencyPipe extends LocaleBasePipe implements PipeTransform
     transform(value: unknown, ...args: unknown[]): string | unknown {
         const [currencyCode, locale] = args;
         if (typeof value === 'number' && typeof currencyCode === 'string') {
-            const activeLocale = typeof locale === 'string' ? locale : this.locale;
+            const activeLocale = this.getActiveLocale(locale);
             const majorUnits = value / 100;
             return new Intl.NumberFormat(activeLocale, { style: 'currency', currency: currencyCode }).format(
                 majorUnits,

+ 1 - 1
packages/admin-ui/src/lib/core/src/shared/pipes/locale-date.pipe.ts

@@ -27,7 +27,7 @@ export class LocaleDatePipe extends LocaleBasePipe implements PipeTransform {
     transform(value: unknown, ...args: unknown[]): unknown {
         const [format, locale] = args;
         if (this.locale || typeof locale === 'string') {
-            const activeLocale = typeof locale === 'string' ? locale : this.locale;
+            const activeLocale = this.getActiveLocale(locale);
             const date =
                 value instanceof Date ? value : typeof value === 'string' ? new Date(value) : undefined;
             if (date) {

+ 1 - 1
packages/admin-ui/src/lib/core/src/shared/pipes/locale-language-name.pipe.ts

@@ -30,7 +30,7 @@ export class LocaleLanguageNamePipe extends LocaleBasePipe implements PipeTransf
         if (typeof value !== 'string') {
             return `Invalid language code "${value as any}"`;
         }
-        const activeLocale = typeof locale === 'string' ? locale : this.locale ?? 'en';
+        const activeLocale = this.getActiveLocale(locale);
 
         // Awaiting TS types for this API: https://github.com/microsoft/TypeScript/pull/44022/files
         const DisplayNames = (Intl as any).DisplayNames;

+ 1 - 1
packages/admin-ui/src/lib/core/src/shared/pipes/locale-region-name.pipe.ts

@@ -30,7 +30,7 @@ export class LocaleRegionNamePipe extends LocaleBasePipe implements PipeTransfor
         if (typeof value !== 'string') {
             return `Invalid region code "${value as any}"`;
         }
-        const activeLocale = typeof locale === 'string' ? locale : this.locale ?? 'en';
+        const activeLocale = this.getActiveLocale(locale);
 
         // Awaiting TS types for this API: https://github.com/microsoft/TypeScript/pull/44022/files
         const DisplayNames = (Intl as any).DisplayNames;