Skip to content

Commit

Permalink
feat(admin-ui): Support for language regions (language + locale)
Browse files Browse the repository at this point in the history
Relates to #1196
  • Loading branch information
michaelbromley committed Dec 1, 2021
1 parent 8f218da commit b5cdbce
Show file tree
Hide file tree
Showing 47 changed files with 708 additions and 120 deletions.
54 changes: 27 additions & 27 deletions packages/admin-ui/i18n-coverage.json
Original file line number Diff line number Diff line change
@@ -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
}
Expand Down
31 changes: 27 additions & 4 deletions packages/admin-ui/src/lib/core/src/common/generated-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -2393,6 +2396,7 @@ export type Mutation = {
setDisplayUiExtensionPoints: Scalars['Boolean'];
setOrderCustomFields?: Maybe<Order>;
setUiLanguage: LanguageCode;
setUiLocale?: Maybe<Scalars['String']>;
setUiTheme: Scalars['String'];
settlePayment: SettlePaymentResult;
settleRefund: SettleRefundResult;
Expand Down Expand Up @@ -2862,6 +2866,11 @@ export type MutationSetUiLanguageArgs = {
};


export type MutationSetUiLocaleArgs = {
locale?: Maybe<Scalars['String']>;
};


export type MutationSetUiThemeArgs = {
theme: Scalars['String'];
};
Expand Down Expand Up @@ -4928,6 +4937,7 @@ export type TransitionPaymentToStateResult = Payment | PaymentStateTransitionErr
export type UiState = {
__typename?: 'UiState';
language: LanguageCode;
locale?: Maybe<Scalars['String']>;
contentLanguage: LanguageCode;
theme: Scalars['String'];
displayUiExtensionPoints: Scalars['Boolean'];
Expand Down Expand Up @@ -5483,10 +5493,18 @@ export type SetAsLoggedOutMutation = { setAsLoggedOut: (

export type SetUiLanguageMutationVariables = Exact<{
languageCode: LanguageCode;
locale?: Maybe<Scalars['String']>;
}>;


export type SetUiLanguageMutation = Pick<Mutation, 'setUiLanguage' | 'setUiLocale'>;

export type SetUiLocaleMutationVariables = Exact<{
locale?: Maybe<Scalars['String']>;
}>;


export type SetUiLanguageMutation = Pick<Mutation, 'setUiLanguage'>;
export type SetUiLocaleMutation = Pick<Mutation, 'setUiLocale'>;

export type SetDisplayUiExtensionPointsMutationVariables = Exact<{
display: Scalars['Boolean'];
Expand Down Expand Up @@ -5530,7 +5548,7 @@ export type GetUiStateQueryVariables = Exact<{ [key: string]: never; }>;

export type GetUiStateQuery = { uiState: (
{ __typename?: 'UiState' }
& Pick<UiState, 'language' | 'contentLanguage' | 'theme' | 'displayUiExtensionPoints'>
& Pick<UiState, 'language' | 'locale' | 'contentLanguage' | 'theme' | 'displayUiExtensionPoints'>
) };

export type GetClientStateQueryVariables = Exact<{ [key: string]: never; }>;
Expand All @@ -5544,7 +5562,7 @@ export type GetClientStateQuery = { networkStatus: (
& UserStatusFragment
), uiState: (
{ __typename?: 'UiState' }
& Pick<UiState, 'language' | 'contentLanguage' | 'theme'>
& Pick<UiState, 'language' | 'locale' | 'contentLanguage' | 'theme' | 'displayUiExtensionPoints'>
) };

export type SetActiveChannelMutationVariables = Exact<{
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<div class="header-actions">
<vdr-channel-switcher *vdrIfMultichannel></vdr-channel-switcher>
<vdr-user-menu [userName]="userName$ | async"
[uiLanguage]="uiLanguage$ | async"
[uiLanguageAndLocale]="uiLanguageAndLocale$ | async"
[availableLanguages]="availableLanguages"
(selectUiLanguage)="selectUiLanguage()"
(logOut)="logOut()"></vdr-user-menu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { UiLanguageSwitcherDialogComponent } from '../ui-language-switcher-dialo
})
export class AppShellComponent implements OnInit {
userName$: Observable<string>;
uiLanguage$: Observable<LanguageCode>;
uiLanguageAndLocale$: Observable<[LanguageCode, string | undefined]>;
availableLanguages: LanguageCode[] = [];

constructor(
Expand All @@ -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);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,75 @@
<ng-template vdrDialogTitle>{{ 'common.select-display-language' | translate }}</ng-template>

<div *ngFor="let code of availableLanguages" >
<button class="btn btn-link btn-sm" (click)="setLanguage(code)">
<clr-icon [attr.shape]="code === currentLanguage ? 'dot-circle' : 'circle'"></clr-icon>
{{ code | uppercase }} ({{ code | localeLanguageName }})
</button>
<div class="clr-row">
<div class="clr-col-md-6">
<clr-select-container>
<label>{{ 'common.language' | translate }}</label>
<select
clrSelect
name="options"
[(ngModel)]="currentLanguage"
(ngModelChange)="updatePreviewLocale()"
>
<option *ngFor="let code of availableLanguages | sort" [value]="code">
{{ code | uppercase }} ({{ code | localeLanguageName }})
</option>
</select>
</clr-select-container>
</div>
<div class="clr-col-md-6">
<clr-datalist-container>
<label>{{ 'common.locale' | translate }}</label>
<input
clrDatalistInput
[(ngModel)]="currentLocale"
(ngModelChange)="updatePreviewLocale()"
[placeholder]="'common.browser-default' | translate"
class="locale"
name="Locale"
/>
<datalist>
<option *ngFor="let locale of availableLocales" [value]="locale">
{{ locale }} ({{ locale | localeRegionName }})
</option>
</datalist>
</clr-datalist-container>
</div>
</div>
<div class="card">
<div class="card-header">
<span class="p2">{{ 'common.sample-formatting' | translate }}:</span><strong>{{ previewLocale | localeLanguageName:previewLocale }}</strong>
</div>
<div class="card-block">
<div class="clr-row">
<div class="clr-col-sm-4">
<vdr-labeled-data [label]="'common.medium-date' | translate">
{{ now | localeDate: 'medium':previewLocale }}
</vdr-labeled-data>
<vdr-labeled-data [label]="'common.short-date' | translate">
{{ now | localeDate: 'short':previewLocale }}
</vdr-labeled-data>
</div>
<div class="clr-col-sm-4">
<select clrSelect name="currency" class="currency" [(ngModel)]="selectedCurrencyCode">
<option *ngFor="let code of availableCurrencyCodes | sort" [value]="code">
{{ code | uppercase }} ({{ code | localeCurrencyName: 'full':previewLocale }})
</option>
</select>
</div>
<div class="clr-col-sm-4">
<vdr-labeled-data [label]="'common.price' | translate">
{{ 12345 | localeCurrency: selectedCurrencyCode:previewLocale }}
</vdr-labeled-data>
</div>
</div>
</div>
</div>
<ng-template vdrDialogButtons>
<button type="button" class="btn" (click)="cancel()">{{ 'common.cancel' | translate }}</button>
<button
type="submit"
(click)="setLanguage()"
class="btn btn-primary"
>
{{ 'common.set-language' | translate }}
</button>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
:host {
}

select.currency {
max-width: 200px;
}

input.locale {
text-transform: uppercase;
}
Loading

0 comments on commit b5cdbce

Please sign in to comment.