From 145c05321dba015fbfc5ee30c520a91605ab9048 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 6 Apr 2021 10:35:41 +0100 Subject: [PATCH] improved language picker (#6890) * improved language picker * fix import path * update tests --- demo-shell/src/app.config.json | 71 ------------------ lib/core/i18n/en.json | 1 + .../language-menu.component.html | 2 - .../language-menu.component.spec.ts | 33 +++++---- .../language-menu/language-menu.component.ts | 35 ++++----- .../language-menu/language-menu.module.ts | 11 ++- ...erface.ts => language-picker.component.ts} | 20 +++-- lib/core/language-menu/public-api.ts | 2 +- lib/core/services/language.service.ts | 73 +++++++++++++++++++ lib/core/services/public-api.ts | 1 + lib/core/services/user-preferences.service.ts | 2 +- 11 files changed, 131 insertions(+), 120 deletions(-) delete mode 100644 lib/core/language-menu/language-menu.component.html rename lib/core/language-menu/{language.interface.ts => language-picker.component.ts} (58%) create mode 100644 lib/core/services/language.service.ts diff --git a/demo-shell/src/app.config.json b/demo-shell/src/app.config.json index 8e948f274f..43d876f707 100644 --- a/demo-shell/src/app.config.json +++ b/demo-shell/src/app.config.json @@ -33,77 +33,6 @@ "name": "Alfresco ADF Application", "copyright": "© 2016 - 2018 Alfresco Software, Inc. All Rights Reserved." }, - "languages": [ - { - "key": "en", - "label": "English" - }, - { - "key": "fr", - "label": "Français" - }, - { - "key": "de", - "label": "Deutsch" - }, - { - "key": "it", - "label": "Italiano" - }, - { - "key": "es", - "label": "Español" - }, - { - "key": "ja", - "label": "日本語" - }, - { - "key": "nl", - "label": "Nederlands" - }, - { - "key": "pt-BR", - "label": "Português (Brasil)" - }, - { - "key": "nb", - "label": "Bokmål" - }, - { - "key": "ru", - "label": "Русский" - }, - { - "key": "zh-CN", - "label": "中文简体" - }, - { - "key": "ar", - "label": "عربى", - "direction": "rtl" - }, - { - "key": "cs", - "label": "Čeština" - }, - { - "key": "pl", - "label": "Polski" - }, - { - "key": "fi", - "label": "Suomi" - }, - { - "key": "da", - "label": "Dansk" - }, - { - "key": "sv", - "label": "Svenska" - } - ], "search": { "filterWithContains": true, "app:fields": [ diff --git a/lib/core/i18n/en.json b/lib/core/i18n/en.json index c6d418db28..2be7dd9f94 100644 --- a/lib/core/i18n/en.json +++ b/lib/core/i18n/en.json @@ -1,5 +1,6 @@ { "ADF": { + "LANGUAGE": "Language", "ROLES": { "ALL": "All", "CONTRIBUTOR": "Contributor", diff --git a/lib/core/language-menu/language-menu.component.html b/lib/core/language-menu/language-menu.component.html deleted file mode 100644 index 16d486ac84..0000000000 --- a/lib/core/language-menu/language-menu.component.html +++ /dev/null @@ -1,2 +0,0 @@ - diff --git a/lib/core/language-menu/language-menu.component.spec.ts b/lib/core/language-menu/language-menu.component.spec.ts index f6db1b3d65..5c1a87c05a 100644 --- a/lib/core/language-menu/language-menu.component.spec.ts +++ b/lib/core/language-menu/language-menu.component.spec.ts @@ -18,10 +18,10 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AppConfigService } from '../app-config/app-config.service'; import { LanguageMenuComponent } from './language-menu.component'; -import { setupTestBed } from '../testing/setup-test-bed'; import { CoreTestingModule } from '../testing/core.testing.module'; import { UserPreferencesService } from '../services/user-preferences.service'; import { TranslateModule } from '@ngx-translate/core'; +import { LanguageService } from '../services/language.service'; describe('LanguageMenuComponent', () => { @@ -29,6 +29,7 @@ describe('LanguageMenuComponent', () => { let component: LanguageMenuComponent; let appConfig: AppConfigService; let userPreferencesService: UserPreferencesService; + let languageService: LanguageService; const languages = [ { @@ -46,33 +47,35 @@ describe('LanguageMenuComponent', () => { } ]; - setupTestBed({ - imports: [ - TranslateModule.forRoot(), - CoreTestingModule - ] - }); - beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + TranslateModule.forRoot(), + CoreTestingModule + ] + }); + fixture = TestBed.createComponent(LanguageMenuComponent); component = fixture.componentInstance; appConfig = TestBed.inject(AppConfigService); userPreferencesService = TestBed.inject(UserPreferencesService); + languageService = TestBed.inject(LanguageService); }); afterEach(() => { fixture.destroy(); }); - it('should fetch the languages from the app config if present', () => { + it('should fetch the languages from the app config if present', async (done) => { + languageService.setLanguages(languages); + fixture.detectChanges(); + await fixture.whenStable(); - expect(component.languages).toEqual([{ key: 'en', label: 'English' }]); - - appConfig.config.languages = languages; - - component.ngOnInit(); - expect(component.languages).toEqual(languages); + component.languages$.subscribe(langs => { + expect(langs).toEqual(languages); + done(); + }); }); it('should change user preference locale', () => { diff --git a/lib/core/language-menu/language-menu.component.ts b/lib/core/language-menu/language-menu.component.ts index 55e2941375..5b98f3bc42 100644 --- a/lib/core/language-menu/language-menu.component.ts +++ b/lib/core/language-menu/language-menu.component.ts @@ -15,35 +15,28 @@ * limitations under the License. */ -import { Component, OnInit } from '@angular/core'; -import { AppConfigService, AppConfigValues } from '../app-config/app-config.service'; -import { UserPreferencesService } from '../services/user-preferences.service'; -import { LanguageItem } from './language.interface'; +import { Component } from '@angular/core'; +import { LanguageItem, LanguageService } from '../services/language.service'; +import { Observable } from 'rxjs'; @Component({ selector: 'adf-language-menu', - templateUrl: 'language-menu.component.html' + template: ` + + ` }) -export class LanguageMenuComponent implements OnInit { +export class LanguageMenuComponent { - languages: Array = [ - { key: 'en', label: 'English'} - ]; + languages$: Observable; - constructor( - private appConfig: AppConfigService, - private userPreference: UserPreferencesService) { - } - - ngOnInit() { - const languagesConfigApp = this.appConfig.get>(AppConfigValues.APP_CONFIG_LANGUAGES_KEY); - if (languagesConfigApp) { - this.languages = languagesConfigApp; - } + constructor(private languageService: LanguageService) { + this.languages$ = languageService.languages$; } changeLanguage(language: LanguageItem) { - this.userPreference.locale = language.key; - this.userPreference.set('textOrientation', language.direction || 'ltr'); + this.languageService.changeLanguage(language); } } diff --git a/lib/core/language-menu/language-menu.module.ts b/lib/core/language-menu/language-menu.module.ts index 3d9823a78f..2af3b8b2ce 100644 --- a/lib/core/language-menu/language-menu.module.ts +++ b/lib/core/language-menu/language-menu.module.ts @@ -20,17 +20,22 @@ import { NgModule } from '@angular/core'; import { MaterialModule } from '../material.module'; import { LanguageMenuComponent } from './language-menu.component'; +import { LanguagePickerComponent } from './language-picker.component'; +import { TranslateModule } from '@ngx-translate/core'; @NgModule({ imports: [ CommonModule, - MaterialModule + MaterialModule, + TranslateModule ], declarations: [ - LanguageMenuComponent + LanguageMenuComponent, + LanguagePickerComponent ], exports: [ - LanguageMenuComponent + LanguageMenuComponent, + LanguagePickerComponent ] }) export class LanguageMenuModule {} diff --git a/lib/core/language-menu/language.interface.ts b/lib/core/language-menu/language-picker.component.ts similarity index 58% rename from lib/core/language-menu/language.interface.ts rename to lib/core/language-menu/language-picker.component.ts index c0fc03bf0d..890d5f75b8 100644 --- a/lib/core/language-menu/language.interface.ts +++ b/lib/core/language-menu/language-picker.component.ts @@ -15,10 +15,18 @@ * limitations under the License. */ -import { Direction } from '@angular/cdk/bidi'; +import { Component } from '@angular/core'; -export interface LanguageItem { - key: string; - label: string; - direction?: Direction; -} +@Component({ + selector: 'adf-picker-button', + template: ` + + + + + ` +}) +export class LanguagePickerComponent {} diff --git a/lib/core/language-menu/public-api.ts b/lib/core/language-menu/public-api.ts index 2d3686278c..46d2b383de 100644 --- a/lib/core/language-menu/public-api.ts +++ b/lib/core/language-menu/public-api.ts @@ -16,5 +16,5 @@ */ export * from './language-menu.component'; -export * from './language.interface'; export * from './language-menu.module'; +export * from './language-picker.component'; diff --git a/lib/core/services/language.service.ts b/lib/core/services/language.service.ts new file mode 100644 index 0000000000..1e0cb1ead9 --- /dev/null +++ b/lib/core/services/language.service.ts @@ -0,0 +1,73 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { Direction } from '@angular/cdk/bidi'; +import { BehaviorSubject } from 'rxjs'; +import { AppConfigService, AppConfigValues } from '../app-config/app-config.service'; +import { UserPreferencesService } from './user-preferences.service'; + +export interface LanguageItem { + key: string; + label: string; + direction?: Direction; +} + +@Injectable({providedIn: 'root'}) +export class LanguageService { + + private languages = new BehaviorSubject([ + {'key': 'de', 'label': 'Deutsch'}, + {'key': 'en', 'label': 'English'}, + {'key': 'es', 'label': 'Español'}, + {'key': 'fr', 'label': 'Français'}, + {'key': 'it', 'label': 'Italiano'}, + {'key': 'ja', 'label': '日本語'}, + {'key': 'nb', 'label': 'Bokmål'}, + {'key': 'nl', 'label': 'Nederlands'}, + {'key': 'pt-BR', 'label': 'Português (Brasil)'}, + {'key': 'ru', 'label': 'Русский'}, + {'key': 'zh-CN', 'label': '中文简体'}, + {'key': 'cs', 'label': 'Čeština'}, + {'key': 'da', 'label': 'Dansk'}, + {'key': 'fi', 'label': 'Suomi'}, + {'key': 'pl', 'label': 'Polski'}, + {'key': 'sv', 'label': 'Svenska'}, + {'key': 'ar', 'label': 'العربية', direction: 'rtl'} + ]); + + languages$ = this.languages.asObservable(); + + constructor( + appConfigService: AppConfigService, + private userPreferencesService: UserPreferencesService) { + + const customLanguages = appConfigService.get>(AppConfigValues.APP_CONFIG_LANGUAGES_KEY); + this.setLanguages(customLanguages); + } + + changeLanguage(language: LanguageItem) { + this.userPreferencesService.locale = language.key; + this.userPreferencesService.set('textOrientation', language.direction || 'ltr'); + } + + setLanguages(items: LanguageItem[]) { + if (items && items.length > 0) { + this.languages.next(items); + } + } +} diff --git a/lib/core/services/public-api.ts b/lib/core/services/public-api.ts index 7508d9fdcc..dd00320236 100644 --- a/lib/core/services/public-api.ts +++ b/lib/core/services/public-api.ts @@ -64,3 +64,4 @@ export * from './identity-role.service'; export * from './version-compatibility.service'; export * from './auth-bearer.interceptor'; export * from './oauth2.service'; +export * from './language.service'; diff --git a/lib/core/services/user-preferences.service.ts b/lib/core/services/user-preferences.service.ts index a1649601e4..0b08446e75 100644 --- a/lib/core/services/user-preferences.service.ts +++ b/lib/core/services/user-preferences.service.ts @@ -19,7 +19,7 @@ import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { Observable, BehaviorSubject } from 'rxjs'; import { AppConfigService, AppConfigValues } from '../app-config/app-config.service'; -import { LanguageItem } from '../language-menu/language.interface'; +import { LanguageItem } from './language.service'; import { StorageService } from './storage.service'; import { distinctUntilChanged, map, filter } from 'rxjs/operators'; import { AlfrescoApiService } from './alfresco-api.service';