mirror of
https://github.com/valitydev/dashboard.git
synced 2024-11-06 02:25:23 +00:00
Support EN and use it by default (#96)
This commit is contained in:
parent
7c38e35b8d
commit
d360c9cdbb
@ -1,3 +1,3 @@
|
||||
files:
|
||||
- source: /src/assets/i18n/**/ru.json
|
||||
translation: /%original_path%/%two_letters_code%.json
|
||||
- source: /src/assets/i18n/**/ru.json
|
||||
translation: /%original_path%/%two_letters_code%.json
|
||||
|
@ -13,7 +13,7 @@ import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { Router } from '@angular/router';
|
||||
import { TRANSLOCO_CONFIG, TRANSLOCO_LOADER, TranslocoConfig, TranslocoModule } from '@ngneat/transloco';
|
||||
import { TRANSLOCO_CONFIG, TRANSLOCO_LOADER, TranslocoModule, translocoConfig } from '@ngneat/transloco';
|
||||
import * as Sentry from '@sentry/angular';
|
||||
|
||||
import { AnapiModule } from '@dsh/api/anapi';
|
||||
@ -32,7 +32,7 @@ import { ENV, environment } from '../environments';
|
||||
import { OrganizationsModule } from './api/organizations';
|
||||
import { AppComponent } from './app.component';
|
||||
import { AuthModule, KeycloakAngularModule, KeycloakService } from './auth';
|
||||
import { ConfigModule, ConfigService } from './config';
|
||||
import { ConfigService } from './config';
|
||||
import { HomeModule } from './home';
|
||||
import { IconsModule, IconsService } from './icons';
|
||||
import { initializer } from './initializer';
|
||||
@ -40,8 +40,7 @@ import { LanguageService } from './language';
|
||||
import { SectionsModule } from './sections';
|
||||
import { SentryErrorHandler } from './sentry-error-handler.service';
|
||||
import { SentryHttpInterceptor } from './sentry-http-interceptor';
|
||||
import { SettingsModule } from './settings';
|
||||
import { ThemeManager, ThemeManagerModule } from './theme-manager';
|
||||
import { ThemeManager } from './theme-manager';
|
||||
import { TranslocoHttpLoaderService } from './transloco-http-loader.service';
|
||||
|
||||
@NgModule({
|
||||
@ -52,10 +51,7 @@ import { TranslocoHttpLoaderService } from './transloco-http-loader.service';
|
||||
BrowserAnimationsModule,
|
||||
SectionsModule,
|
||||
AuthModule,
|
||||
ThemeManagerModule,
|
||||
ConfigModule,
|
||||
HomeModule,
|
||||
SettingsModule,
|
||||
KeycloakAngularModule,
|
||||
HttpClientModule,
|
||||
TranslocoModule,
|
||||
@ -98,13 +94,13 @@ import { TranslocoHttpLoaderService } from './transloco-http-loader.service';
|
||||
{ provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { appearance: 'outline' } },
|
||||
{
|
||||
provide: TRANSLOCO_CONFIG,
|
||||
useValue: {
|
||||
reRenderOnLangChange: false,
|
||||
defaultLang: 'ru',
|
||||
availableLangs: ['ru'],
|
||||
useValue: translocoConfig({
|
||||
availableLangs: ['en', 'ru'],
|
||||
defaultLang: 'en',
|
||||
fallbackLang: 'ru',
|
||||
reRenderOnLangChange: true,
|
||||
prodMode: environment.production,
|
||||
} as TranslocoConfig,
|
||||
}),
|
||||
},
|
||||
{ provide: TRANSLOCO_LOADER, useClass: TranslocoHttpLoaderService },
|
||||
{ provide: ENV, useValue: environment },
|
||||
|
@ -1,8 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ConfigService } from './config.service';
|
||||
|
||||
@NgModule({
|
||||
providers: [ConfigService],
|
||||
})
|
||||
export class ConfigModule {}
|
@ -4,7 +4,7 @@ import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { BASE_CONFIG, Config } from './config';
|
||||
|
||||
@Injectable()
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ConfigService extends BASE_CONFIG {
|
||||
isInit$ = new BehaviorSubject(false);
|
||||
|
||||
|
@ -1,2 +1 @@
|
||||
export * from './config.module';
|
||||
export * from './config.service';
|
||||
|
@ -3,11 +3,10 @@ import { NgModule } from '@angular/core';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { ConfigModule } from '../../config';
|
||||
import { BrandComponent } from './brand.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule, MatIconModule, HttpClientModule, ConfigModule],
|
||||
imports: [RouterModule, MatIconModule, HttpClientModule],
|
||||
declarations: [BrandComponent],
|
||||
exports: [BrandComponent],
|
||||
})
|
||||
|
@ -4,7 +4,6 @@ import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { ConfigModule } from '../config';
|
||||
import { HomeComponent } from './home.component';
|
||||
import { LaptopGridModule } from './laptop-grid/laptop-grid.module';
|
||||
import { MobileGridModule } from './mobile-grid/mobile-grid.module';
|
||||
@ -19,7 +18,6 @@ import { ToolbarModule } from './toolbar';
|
||||
MatIconModule,
|
||||
MobileGridModule,
|
||||
LaptopGridModule,
|
||||
ConfigModule,
|
||||
],
|
||||
declarations: [HomeComponent],
|
||||
exports: [HomeComponent],
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { LanguageModule } from '../language';
|
||||
import { HumanizeDurationService } from './humanize-duration.service';
|
||||
import { HumanizedDurationPipe } from './humanized-duration.pipe';
|
||||
|
||||
@NgModule({
|
||||
imports: [LanguageModule],
|
||||
declarations: [HumanizedDurationPipe],
|
||||
providers: [HumanizeDurationService],
|
||||
exports: [HumanizedDurationPipe],
|
||||
|
@ -4,7 +4,7 @@ import * as humanizeDuration from 'humanize-duration';
|
||||
import moment from 'moment';
|
||||
import { Observable, of } from 'rxjs';
|
||||
|
||||
import { Language, LanguageService } from '../language';
|
||||
import { LanguageService } from '../language';
|
||||
|
||||
export type Value = number | string | moment.Moment | Date;
|
||||
|
||||
@ -25,7 +25,7 @@ export class HumanizeDurationService {
|
||||
|
||||
private get duration() {
|
||||
return humanizeDuration.humanizer({
|
||||
language: this.languageService.active || Language.En,
|
||||
language: this.languageService.active || 'en',
|
||||
round: true,
|
||||
delimiter: ' ',
|
||||
});
|
||||
|
@ -1,9 +1,9 @@
|
||||
import localeEn from '@angular/common/locales/en';
|
||||
import localeRu from '@angular/common/locales/ru';
|
||||
|
||||
import { Language } from './language';
|
||||
import { Language } from './languages';
|
||||
|
||||
export const ANGULAR_LOCALE_DATA: { [language in Language]: any } = {
|
||||
[Language.Ru]: localeRu,
|
||||
[Language.En]: localeEn,
|
||||
ru: localeRu,
|
||||
en: localeEn,
|
||||
};
|
||||
|
@ -1,3 +1,2 @@
|
||||
export * from './language.module';
|
||||
export * from './language.service';
|
||||
export * from './language';
|
||||
export * from './languages';
|
||||
|
@ -1,10 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { SettingsModule } from '../settings';
|
||||
import { LanguageService } from './language.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [SettingsModule],
|
||||
providers: [LanguageService],
|
||||
})
|
||||
export class LanguageModule {}
|
@ -5,44 +5,40 @@ import * as moment from 'moment';
|
||||
|
||||
import { SettingsService } from '../settings';
|
||||
import { ANGULAR_LOCALE_DATA } from './angular-locale-data';
|
||||
import { Language } from './language';
|
||||
import { LANGUAGES, Language } from './languages';
|
||||
|
||||
@Injectable()
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class LanguageService {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
private static readonly KEY = 'language';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
active: Language;
|
||||
|
||||
private static readonly key = 'language';
|
||||
|
||||
constructor(private settingsService: SettingsService, private transloco: TranslocoService) {}
|
||||
|
||||
async init() {
|
||||
const language = this.settingsService.getLocalStorageItem(LanguageService.KEY);
|
||||
const correctedLanguage = this.getCorrectLanguage(language);
|
||||
await this.change(correctedLanguage);
|
||||
// TODO: Use after language change support starts
|
||||
// const storageLang = this.settingsService.getLocalStorageItem(LanguageService.key);
|
||||
const storageLang = null;
|
||||
let language: Language;
|
||||
if (Array.from<string>(LANGUAGES).includes(storageLang)) {
|
||||
language = storageLang as Language;
|
||||
} else {
|
||||
const browserLang: string =
|
||||
navigator.language || (navigator as never as Record<PropertyKey, string>).userLanguage;
|
||||
language = Array.from<string>(LANGUAGES).includes(browserLang)
|
||||
? (browserLang as Language)
|
||||
: this.active || 'en';
|
||||
}
|
||||
await this.set(language);
|
||||
}
|
||||
|
||||
async change(language: Language) {
|
||||
registerLocaleData(ANGULAR_LOCALE_DATA[language], language);
|
||||
if (language !== Language.En) {
|
||||
await import(`moment/locale/${language}`);
|
||||
}
|
||||
moment.locale(language);
|
||||
this.settingsService.setLocalStorageItem(LanguageService.KEY, language);
|
||||
this.transloco.setActiveLang(language);
|
||||
// TODO: Make it public after language change support starts
|
||||
private async set(language: Language) {
|
||||
this.active = language;
|
||||
}
|
||||
|
||||
private getCorrectLanguage(language: Language | string): Language {
|
||||
if (!Object.values<string>(Language).includes(language)) {
|
||||
return this.getRecommended();
|
||||
}
|
||||
return language as Language;
|
||||
}
|
||||
|
||||
private getRecommended(): Language {
|
||||
const language = navigator.language || (navigator as any).userLanguage;
|
||||
return Object.values(Language).includes(language) ? language : this.active || Language.Ru;
|
||||
registerLocaleData(ANGULAR_LOCALE_DATA[language], language);
|
||||
if (language !== 'en') await import(`moment/locale/${language}`);
|
||||
moment.locale(language);
|
||||
this.settingsService.setLocalStorageItem(LanguageService.key, language);
|
||||
this.transloco.setActiveLang(language);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
export enum Language {
|
||||
Ru = 'ru',
|
||||
En = 'en',
|
||||
}
|
4
src/app/language/languages.ts
Normal file
4
src/app/language/languages.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { ValuesType } from 'utility-types';
|
||||
|
||||
export const LANGUAGES = ['ru', 'en'] as const;
|
||||
export type Language = ValuesType<typeof LANGUAGES>;
|
@ -24,7 +24,6 @@ import { LayoutModule } from '@dsh/components/layout';
|
||||
import { StateNavModule } from '@dsh/components/navigation';
|
||||
import { ShowMorePanelModule } from '@dsh/components/show-more-panel';
|
||||
|
||||
import { LanguageModule } from '../../../../language';
|
||||
import { CreateInvoiceModule } from './create-invoice';
|
||||
import { InvoicesListModule } from './invoices-list';
|
||||
import { InvoicesRoutingModule } from './invoices-routing.module';
|
||||
@ -49,7 +48,6 @@ import { InvoicesComponent } from './invoices.component';
|
||||
MatSnackBarModule,
|
||||
StateNavModule,
|
||||
TranslocoModule,
|
||||
LanguageModule,
|
||||
MatMenuModule,
|
||||
EmptySearchResultModule,
|
||||
MatDialogModule,
|
||||
|
@ -1,2 +1 @@
|
||||
export * from './settings.module';
|
||||
export * from './settings.service';
|
||||
|
@ -1,8 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { SettingsService } from './settings.service';
|
||||
|
||||
@NgModule({
|
||||
providers: [SettingsService],
|
||||
})
|
||||
export class SettingsModule {}
|
@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class SettingsService {
|
||||
setLocalStorageItem(key: string, value: string) {
|
||||
localStorage.setItem(this.getKeyName(key), value);
|
||||
|
@ -1,5 +1,4 @@
|
||||
export * from './theme-manager.service';
|
||||
export * from './theme-manager.module';
|
||||
export * from './types/palette-color';
|
||||
export * from './types/status-color';
|
||||
export * from './types/theme-name';
|
||||
|
@ -1,11 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ConfigModule } from '../config';
|
||||
import { SettingsModule } from '../settings';
|
||||
import { ThemeManager } from './theme-manager.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [SettingsModule, ConfigModule],
|
||||
providers: [ThemeManager],
|
||||
})
|
||||
export class ThemeManagerModule {}
|
@ -8,7 +8,7 @@ import { isTheme } from './utils/is-theme';
|
||||
|
||||
const THEME_POSTFIX = 'theme';
|
||||
|
||||
@Injectable()
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ThemeManager {
|
||||
current: ThemeName;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
langs: ['ru'],
|
||||
langs: ['en', 'ru'],
|
||||
keysManager: {
|
||||
input: './',
|
||||
fileFormat: 'json',
|
||||
|
Loading…
Reference in New Issue
Block a user