diff --git a/packages/admin-ui/i18n-coverage.json b/packages/admin-ui/i18n-coverage.json index 9019784737..7919ebcce8 100644 --- a/packages/admin-ui/i18n-coverage.json +++ b/packages/admin-ui/i18n-coverage.json @@ -1,69 +1,69 @@ { - "generatedOn": "2021-11-26T11:42:42.094Z", - "lastCommit": "cee98091eeb0fedc5b5269bdee8a8b237f0c7c8e", + "generatedOn": "2021-12-01T14:27:05.793Z", + "lastCommit": "8f218daf16959f6c8aa6f1d0262aeb124bd4214b", "translationStatus": { "cs": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 591, - "percentage": 94 + "percentage": 93 }, "de": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 570, - "percentage": 91 + "percentage": 90 }, "en": { - "tokenCount": 628, - "translatedCount": 627, - "percentage": 100 + "tokenCount": 634, + "translatedCount": 628, + "percentage": 99 }, "es": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 623, - "percentage": 99 + "percentage": 98 }, "fr": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 613, - "percentage": 98 + "percentage": 97 }, "it": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 621, - "percentage": 99 + "percentage": 98 }, "pl": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 405, "percentage": 64 }, "pt_BR": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 588, - "percentage": 94 + "percentage": 93 }, "pt_PT": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 622, - "percentage": 99 + "percentage": 98 }, "ru": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 621, - "percentage": 99 + "percentage": 98 }, "uk": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 621, - "percentage": 99 + "percentage": 98 }, "zh_Hans": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 558, - "percentage": 89 + "percentage": 88 }, "zh_Hant": { - "tokenCount": 628, + "tokenCount": 634, "translatedCount": 385, "percentage": 61 } diff --git a/packages/admin-ui/src/lib/core/src/common/generated-types.ts b/packages/admin-ui/src/lib/core/src/common/generated-types.ts index 36d3124b1e..2cf1291443 100644 --- a/packages/admin-ui/src/lib/core/src/common/generated-types.ts +++ b/packages/admin-ui/src/lib/core/src/common/generated-types.ts @@ -2243,7 +2243,10 @@ export type Mutation = { addCustomersToGroup: CustomerGroup; addFulfillmentToOrder: AddFulfillmentToOrderResult; /** - * Used to manually create a new Payment against an Order. This is used when a completed Order + * Used to manually create a new Payment against an Order. + * This can be used by an Administrator when an Order is in the ArrangingPayment state. + * + * It is also used when a completed Order * has been modified (using `modifyOrder`) and the price has increased. The extra payment * can then be manually arranged by the administrator, and the details used to create a new * Payment. @@ -2393,6 +2396,7 @@ export type Mutation = { setDisplayUiExtensionPoints: Scalars['Boolean']; setOrderCustomFields?: Maybe; setUiLanguage: LanguageCode; + setUiLocale?: Maybe; setUiTheme: Scalars['String']; settlePayment: SettlePaymentResult; settleRefund: SettleRefundResult; @@ -2862,6 +2866,11 @@ export type MutationSetUiLanguageArgs = { }; +export type MutationSetUiLocaleArgs = { + locale?: Maybe; +}; + + export type MutationSetUiThemeArgs = { theme: Scalars['String']; }; @@ -4928,6 +4937,7 @@ export type TransitionPaymentToStateResult = Payment | PaymentStateTransitionErr export type UiState = { __typename?: 'UiState'; language: LanguageCode; + locale?: Maybe; contentLanguage: LanguageCode; theme: Scalars['String']; displayUiExtensionPoints: Scalars['Boolean']; @@ -5483,10 +5493,18 @@ export type SetAsLoggedOutMutation = { setAsLoggedOut: ( export type SetUiLanguageMutationVariables = Exact<{ languageCode: LanguageCode; + locale?: Maybe; +}>; + + +export type SetUiLanguageMutation = Pick; + +export type SetUiLocaleMutationVariables = Exact<{ + locale?: Maybe; }>; -export type SetUiLanguageMutation = Pick; +export type SetUiLocaleMutation = Pick; export type SetDisplayUiExtensionPointsMutationVariables = Exact<{ display: Scalars['Boolean']; @@ -5530,7 +5548,7 @@ export type GetUiStateQueryVariables = Exact<{ [key: string]: never; }>; export type GetUiStateQuery = { uiState: ( { __typename?: 'UiState' } - & Pick + & Pick ) }; export type GetClientStateQueryVariables = Exact<{ [key: string]: never; }>; @@ -5544,7 +5562,7 @@ export type GetClientStateQuery = { networkStatus: ( & UserStatusFragment ), uiState: ( { __typename?: 'UiState' } - & Pick + & Pick ) }; export type SetActiveChannelMutationVariables = Exact<{ @@ -9082,6 +9100,11 @@ export namespace SetUiLanguage { export type Mutation = SetUiLanguageMutation; } +export namespace SetUiLocale { + export type Variables = SetUiLocaleMutationVariables; + export type Mutation = SetUiLocaleMutation; +} + export namespace SetDisplayUiExtensionPoints { export type Variables = SetDisplayUiExtensionPointsMutationVariables; export type Mutation = SetDisplayUiExtensionPointsMutation; diff --git a/packages/admin-ui/src/lib/core/src/common/utilities/get-default-ui-language.ts b/packages/admin-ui/src/lib/core/src/common/utilities/get-default-ui-language.ts index 27219e2e7c..d08de08d5c 100644 --- a/packages/admin-ui/src/lib/core/src/common/utilities/get-default-ui-language.ts +++ b/packages/admin-ui/src/lib/core/src/common/utilities/get-default-ui-language.ts @@ -4,3 +4,11 @@ import { LanguageCode } from '../generated-types'; export function getDefaultUiLanguage(): LanguageCode { return getAppConfig().defaultLanguage; } + +export function getDefaultUiLocale(): string | undefined { + const defaultLocale = getAppConfig().defaultLocale; + if (defaultLocale) { + return defaultLocale; + } + return navigator.language.split('-')[1]?.toUpperCase(); +} diff --git a/packages/admin-ui/src/lib/core/src/components/app-shell/app-shell.component.html b/packages/admin-ui/src/lib/core/src/components/app-shell/app-shell.component.html index aa90081ce0..4c140311ed 100644 --- a/packages/admin-ui/src/lib/core/src/components/app-shell/app-shell.component.html +++ b/packages/admin-ui/src/lib/core/src/components/app-shell/app-shell.component.html @@ -7,7 +7,7 @@
diff --git a/packages/admin-ui/src/lib/core/src/components/app-shell/app-shell.component.ts b/packages/admin-ui/src/lib/core/src/components/app-shell/app-shell.component.ts index 9ae073e919..a0b0e1dcee 100644 --- a/packages/admin-ui/src/lib/core/src/components/app-shell/app-shell.component.ts +++ b/packages/admin-ui/src/lib/core/src/components/app-shell/app-shell.component.ts @@ -19,7 +19,7 @@ import { UiLanguageSwitcherDialogComponent } from '../ui-language-switcher-dialo }) export class AppShellComponent implements OnInit { userName$: Observable; - uiLanguage$: Observable; + uiLanguageAndLocale$: Observable<[LanguageCode, string | undefined]>; availableLanguages: LanguageCode[] = []; constructor( @@ -35,30 +35,36 @@ export class AppShellComponent implements OnInit { this.userName$ = this.dataService.client .userStatus() .single$.pipe(map(data => data.userStatus.username)); - this.uiLanguage$ = this.dataService.client.uiState().stream$.pipe(map(data => data.uiState.language)); + this.uiLanguageAndLocale$ = this.dataService.client + .uiState() + .stream$.pipe(map(({ uiState }) => [uiState.language, uiState.locale ?? undefined])); this.availableLanguages = this.i18nService.availableLanguages; } selectUiLanguage() { - this.uiLanguage$ + this.uiLanguageAndLocale$ .pipe( take(1), - switchMap(currentLanguage => + switchMap(([currentLanguage, currentLocale]) => this.modalService.fromComponent(UiLanguageSwitcherDialogComponent, { closable: true, - size: 'md', + size: 'lg', locals: { availableLanguages: this.availableLanguages, currentLanguage, + currentLocale, }, }), ), - switchMap(value => (value ? this.dataService.client.setUiLanguage(value) : EMPTY)), + switchMap(result => + result ? this.dataService.client.setUiLanguage(result[0], result[1]) : EMPTY, + ), ) .subscribe(result => { if (result.setUiLanguage) { this.i18nService.setLanguage(result.setUiLanguage); this.localStorageService.set('uiLanguageCode', result.setUiLanguage); + this.localStorageService.set('uiLocale', result.setUiLocale ?? undefined); } }); } diff --git a/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.html b/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.html index aeb4b74c76..988de2a740 100644 --- a/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.html +++ b/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.html @@ -1,8 +1,75 @@ {{ 'common.select-display-language' | translate }} - -
- +
+
+ + + + +
+
+ + + + + + + +
+
+
+
+ {{ 'common.sample-formatting' | translate }}:{{ previewLocale | localeLanguageName:previewLocale }} +
+
+
+
+ + {{ now | localeDate: 'medium':previewLocale }} + + + {{ now | localeDate: 'short':previewLocale }} + +
+
+ +
+
+ + {{ 12345 | localeCurrency: selectedCurrencyCode:previewLocale }} + +
+
+
+ + + + diff --git a/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.scss b/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.scss index 5cfbcc9657..8b7190fb62 100644 --- a/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.scss +++ b/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.scss @@ -1,3 +1,10 @@ :host { } +select.currency { + max-width: 200px; +} + +input.locale { + text-transform: uppercase; +} diff --git a/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.ts b/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.ts index 6df9011b37..dfb5f2f490 100644 --- a/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.ts +++ b/packages/admin-ui/src/lib/core/src/components/ui-language-switcher-dialog/ui-language-switcher-dialog.component.ts @@ -1,6 +1,6 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { LanguageCode } from '../../common/generated-types'; +import { CurrencyCode, LanguageCode } from '../../common/generated-types'; import { Dialog } from '../../providers/modal/modal.service'; @Component({ @@ -9,12 +9,295 @@ import { Dialog } from '../../providers/modal/modal.service'; styleUrls: ['./ui-language-switcher-dialog.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class UiLanguageSwitcherDialogComponent implements Dialog { - resolveWith: (result?: LanguageCode) => void; +export class UiLanguageSwitcherDialogComponent implements Dialog<[LanguageCode, string | undefined]>, OnInit { + resolveWith: (result?: [LanguageCode, string | undefined]) => void; currentLanguage: LanguageCode; availableLanguages: LanguageCode[] = []; + currentLocale: string | undefined; + availableLocales: string[] = [ + 'AF', + 'AL', + 'DZ', + 'AS', + 'AD', + 'AO', + 'AI', + 'AQ', + 'AG', + 'AR', + 'AM', + 'AW', + 'AU', + 'AT', + 'AZ', + 'BS', + 'BH', + 'BD', + 'BB', + 'BY', + 'BE', + 'BZ', + 'BJ', + 'BM', + 'BT', + 'BO', + 'BQ', + 'BA', + 'BW', + 'BV', + 'BR', + 'IO', + 'BN', + 'BG', + 'BF', + 'BI', + 'CV', + 'KH', + 'CM', + 'CA', + 'KY', + 'CF', + 'TD', + 'CL', + 'CN', + 'CX', + 'CC', + 'CO', + 'KM', + 'CD', + 'CG', + 'CK', + 'CR', + 'HR', + 'CU', + 'CW', + 'CY', + 'CZ', + 'CI', + 'DK', + 'DJ', + 'DM', + 'DO', + 'EC', + 'EG', + 'SV', + 'GQ', + 'ER', + 'EE', + 'SZ', + 'ET', + 'FK', + 'FO', + 'FJ', + 'FI', + 'FR', + 'GF', + 'PF', + 'TF', + 'GA', + 'GM', + 'GE', + 'DE', + 'GH', + 'GI', + 'GR', + 'GL', + 'GD', + 'GP', + 'GU', + 'GT', + 'GG', + 'GN', + 'GW', + 'GY', + 'HT', + 'HM', + 'VA', + 'HN', + 'HK', + 'HU', + 'IS', + 'IN', + 'ID', + 'IR', + 'IQ', + 'IE', + 'IM', + 'IL', + 'IT', + 'JM', + 'JP', + 'JE', + 'JO', + 'KZ', + 'KE', + 'KI', + 'KP', + 'KR', + 'KW', + 'KG', + 'LA', + 'LV', + 'LB', + 'LS', + 'LR', + 'LY', + 'LI', + 'LT', + 'LU', + 'MO', + 'MG', + 'MW', + 'MY', + 'MV', + 'ML', + 'MT', + 'MH', + 'MQ', + 'MR', + 'MU', + 'YT', + 'MX', + 'FM', + 'MD', + 'MC', + 'MN', + 'ME', + 'MS', + 'MA', + 'MZ', + 'MM', + 'NA', + 'NR', + 'NP', + 'NL', + 'NC', + 'NZ', + 'NI', + 'NE', + 'NG', + 'NU', + 'NF', + 'MK', + 'MP', + 'NO', + 'OM', + 'PK', + 'PW', + 'PS', + 'PA', + 'PG', + 'PY', + 'PE', + 'PH', + 'PN', + 'PL', + 'PT', + 'PR', + 'QA', + 'RO', + 'RU', + 'RW', + 'RE', + 'BL', + 'SH', + 'KN', + 'LC', + 'MF', + 'PM', + 'VC', + 'WS', + 'SM', + 'ST', + 'SA', + 'SN', + 'RS', + 'SC', + 'SL', + 'SG', + 'SX', + 'SK', + 'SI', + 'SB', + 'SO', + 'ZA', + 'GS', + 'SS', + 'ES', + 'LK', + 'SD', + 'SR', + 'SJ', + 'SE', + 'CH', + 'SY', + 'TW', + 'TJ', + 'TZ', + 'TH', + 'TL', + 'TG', + 'TK', + 'TO', + 'TT', + 'TN', + 'TR', + 'TM', + 'TC', + 'TV', + 'UG', + 'UA', + 'AE', + 'GB', + 'UM', + 'US', + 'UY', + 'UZ', + 'VU', + 'VE', + 'VN', + 'VG', + 'VI', + 'WF', + 'EH', + 'YE', + 'ZM', + 'ZW', + 'AX', + ]; + availableCurrencyCodes = Object.values(CurrencyCode); + selectedCurrencyCode = 'USD'; + previewLocale: string; + readonly browserDefaultLocale: string | undefined; + readonly now = new Date().toISOString(); - setLanguage(languageCode: LanguageCode) { - this.resolveWith(languageCode); + constructor() { + const browserLanguage = navigator.language.split('-'); + this.browserDefaultLocale = browserLanguage.length === 1 ? undefined : browserLanguage[1]; + } + + ngOnInit() { + this.updatePreviewLocale(); + } + + updatePreviewLocale() { + if (!this.currentLocale || this.currentLocale.length === 0 || this.currentLocale.length === 2) { + this.previewLocale = this.createLocaleString(this.currentLanguage, this.currentLocale); + } + } + + setLanguage() { + this.resolveWith([this.currentLanguage, this.currentLocale?.toUpperCase()]); + } + + cancel() { + this.resolveWith(); + } + + private createLocaleString(languageCode: LanguageCode, region?: string): string { + if (!region) { + return languageCode; + } + return [languageCode, region.toUpperCase()].join('-'); } } diff --git a/packages/admin-ui/src/lib/core/src/components/user-menu/user-menu.component.html b/packages/admin-ui/src/lib/core/src/components/user-menu/user-menu.component.html index 82c904f238..ecc2f73680 100644 --- a/packages/admin-ui/src/lib/core/src/components/user-menu/user-menu.component.html +++ b/packages/admin-ui/src/lib/core/src/components/user-menu/user-menu.component.html @@ -15,7 +15,7 @@ (click)="selectUiLanguage.emit()" [title]="'common.select-display-language' | translate" > - {{ uiLanguage | localeLanguageName }} + {{ uiLanguageAndLocale?.[0] | localeLanguageName }}