projects/prestations-ng/src/sdk-dictionary/sdk-dictionary.service.ts
Properties |
|
Methods |
constructor(httpClient: HttpClient, growlService: GrowlBrokerService, validationService: ValidationHandlerService)
|
||||||||||||
Parameters :
|
changeLanguage | ||||||
changeLanguage(code: string)
|
||||||
Parameters :
Returns :
void
|
getAvailableLanguages |
getAvailableLanguages()
|
Returns :
Observable<Language[]>
|
getCurrentLanguageCode |
getCurrentLanguageCode()
|
Returns :
Observable<string>
|
getDictionary |
getDictionary()
|
Returns :
Observable<DictionaryType>
|
getKey | |||||||||
getKey(key: string, placeholders?: PlaceholderType)
|
|||||||||
Parameters :
Returns :
Observable<string>
|
getKeySync | |||||||||
getKeySync(key: string, placeholders?: PlaceholderType)
|
|||||||||
Parameters :
Returns :
string
|
Private getNavigatorLanguageCodeOrDefault |
getNavigatorLanguageCodeOrDefault()
|
Returns :
string
|
getPluralMarkerSync | ||||||
getPluralMarkerSync(count: number)
|
||||||
Parameters :
Returns :
string
|
setDefaultLanguageCode | ||||||
setDefaultLanguageCode(code: string)
|
||||||
Parameters :
Returns :
void
|
Private Readonly availableLanguagesObservable |
Type : Observable<Language[]>
|
Private defaultLanguageCode |
Type : string
|
Default value : 'fr'
|
Private dictionary |
Type : DictionaryType
|
Private Readonly dictionaryObservable |
Type : Observable<DictionaryType>
|
Private Readonly languageCodeSubject |
Default value : new BehaviorSubject<string>(
this.getNavigatorLanguageCodeOrDefault()
)
|
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
import { catchError, map, shareReplay, switchMap, tap } from 'rxjs/operators';
import { GrowlBrokerService } from '../foehn-growl/growl-broker.service';
import { GrowlType } from '../foehn-growl/growl-types';
import { ValidationHandlerService } from '../validation/validation-handler.service';
// eslint-disable-next-line import/no-cycle
import { DEFAULT_DICTIONARY } from './default-dictionary';
export const DICTIONARY_BASE_URL = 'api/dictionary';
export interface PlaceholderType {
[key: string]: string;
}
export interface DictionaryType {
[key: string]: string;
}
export interface Language {
code: string;
label: string;
}
/**
* @param value to search in
* @param placeholders to be replaced
* @returns string
*/
export const replaceAll = (
value: string,
placeholders?: PlaceholderType
): string => {
if (!placeholders) {
return value;
}
return Object.keys(placeholders).reduce((result, key) => {
const valueToReplace = placeholders[key];
return result.replace(new RegExp(`{${key}}`, 'g'), valueToReplace);
}, value);
};
/**
* @param dictionary holding all keys
* @param key from dictionary
* @param placeholders to be replaced
* @returns string
*/
function getKeyOrDefault(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
dictionary: any,
key: string,
placeholders?: PlaceholderType
): string {
return replaceAll(
dictionary[key] || DEFAULT_DICTIONARY[key] || key,
placeholders
);
}
@Injectable({
providedIn: 'root'
})
export class SdkDictionaryService {
private dictionary: DictionaryType;
private defaultLanguageCode = 'fr';
private readonly dictionaryObservable: Observable<DictionaryType>;
private readonly availableLanguagesObservable: Observable<Language[]>;
private readonly languageCodeSubject = new BehaviorSubject<string>(
this.getNavigatorLanguageCodeOrDefault()
);
constructor(
private httpClient: HttpClient,
private growlService: GrowlBrokerService,
private validationService: ValidationHandlerService
) {
this.availableLanguagesObservable = this.httpClient
.get<Language[]>(`${DICTIONARY_BASE_URL}/languages`)
.pipe(
catchError((e: unknown) => {
console.error(e);
growlService.addWithType(
GrowlType.DANGER,
'Impossible de récupérer les langues disponibles'
);
return of([]);
}),
shareReplay(1)
);
this.dictionaryObservable = this.getCurrentLanguageCode().pipe(
switchMap(languageCode => {
const url =
DICTIONARY_BASE_URL +
(!!languageCode ? `/${languageCode}` : '');
return this.httpClient.get<DictionaryType>(url).pipe(
catchError((e: unknown) => {
console.error(e);
growlService.addWithType(
GrowlType.DANGER,
'Impossible de récupérer les valeurs du dictionnaire'
);
return of({});
}),
tap(dictionary => {
this.dictionary = dictionary;
})
);
}),
shareReplay(1)
);
}
getDictionary(): Observable<DictionaryType> {
return this.dictionaryObservable;
}
getAvailableLanguages(): Observable<Language[]> {
return this.availableLanguagesObservable;
}
getKey(key: string, placeholders?: PlaceholderType): Observable<string> {
return this.dictionaryObservable.pipe(
map(dictionary => getKeyOrDefault(dictionary, key, placeholders))
);
}
getKeySync(key: string, placeholders?: PlaceholderType): string {
if (!this.dictionary) {
throw new Error('Dictionary not initialized.');
}
return getKeyOrDefault(this.dictionary, key, placeholders);
}
getPluralMarkerSync(count: number): string {
if (!count || count === 1) {
return '';
}
return this.getKeySync('plural-marker');
}
changeLanguage(code: string): void {
if (!!code && this.languageCodeSubject.getValue() !== code) {
this.languageCodeSubject.next(code);
}
}
getCurrentLanguageCode(): Observable<string> {
return combineLatest([
this.availableLanguagesObservable,
this.languageCodeSubject.asObservable()
]).pipe(
switchMap(([availableLanguageCodes, languageCode]) => {
const matchedLanguage = availableLanguageCodes.find(
lc => lc.code === languageCode
);
if (!!matchedLanguage && !!matchedLanguage.code) {
return of(matchedLanguage.code);
}
return of(this.defaultLanguageCode);
}),
tap(() => {
// reset errors as they are translated in the backend
this.validationService.updateErrors([]);
}),
shareReplay(1)
);
}
setDefaultLanguageCode(code: string): void {
this.defaultLanguageCode = code;
this.languageCodeSubject.next(this.getNavigatorLanguageCodeOrDefault());
}
private getNavigatorLanguageCodeOrDefault(): string {
return !!navigator && !!navigator.language
? navigator.language.split('-')[0]
: this.defaultLanguageCode;
}
}