translations lib l10n added

This commit is contained in:
geek 2018-03-06 18:55:05 +09:00
parent 7e1c1699e5
commit 98e93dce2f
17 changed files with 203 additions and 33 deletions

View File

@ -42,7 +42,8 @@
"ngx-perfect-scrollbar": "^5.3.1", "ngx-perfect-scrollbar": "^5.3.1",
"rxjs": "^5.5.6", "rxjs": "^5.5.6",
"url-join": "^4.0.0", "url-join": "^4.0.0",
"zone.js": "^0.8.20" "zone.js": "^0.8.20",
"angular-l10n": "^4.1.5"
}, },
"devDependencies": { "devDependencies": {
"@angular/cli": "1.6.5", "@angular/cli": "1.6.5",

View File

@ -1,5 +1,5 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
const routes: Routes = [ const routes: Routes = [
{ path: '', loadChildren: './pages/pages.module#PagesModule' }, { path: '', loadChildren: './pages/pages.module#PagesModule' },
@ -9,7 +9,7 @@ const routes: Routes = [
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true})], imports: [RouterModule.forRoot(routes, {useHash: true, preloadingStrategy: PreloadAllModules})],
exports: [RouterModule], exports: [RouterModule],
}) })
export class AppRoutingModule { } export class AppRoutingModule { }

View File

@ -1,6 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule, Title } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
@ -16,6 +16,40 @@ import { environment } from '../environments/environment';
import { RESTService } from 'packages/commons/service/rest.service'; import { RESTService } from 'packages/commons/service/rest.service';
import { RPCService } from 'packages/commons/service/rpc.service'; import { RPCService } from 'packages/commons/service/rpc.service';
import {
L10nConfig,
L10nLoader,
LocalizationModule,
LocaleValidationModule,
StorageStrategy,
ProviderType
} from 'angular-l10n';
const l10nConfig: L10nConfig = {
locale: {
languages: [
{ code: 'en', dir: 'ltr' },
{ code: 'kr', dir: 'ltr' },
],
defaultLocale: { languageCode: 'en', countryCode: 'US' },
storage: StorageStrategy.Cookie,
cookieExpiration: 30
},
translation: {
providers: [
{ type: ProviderType.Static, prefix: './assets/translations/of-' }
],
caching: true,
composedKeySeparator: '.',
missingValue: 'No key',
i18nPlural: true
}
};
export function initL10n(l10nLoader: L10nLoader): Function {
return () => l10nLoader.load();
}
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent, AppComponent,
@ -28,11 +62,20 @@ import { RPCService } from 'packages/commons/service/rpc.service';
MaterialModule, MaterialModule,
CovalentModule, CovalentModule,
HttpClientModule, HttpClientModule,
LocalizationModule.forRoot(l10nConfig),
LocaleValidationModule.forRoot()
], ],
providers: [ providers: [
{provide: 'REST_BASE_URL', useValue: environment.restBaseURL}, {provide: 'REST_BASE_URL', useValue: environment.restBaseURL},
{provide: 'RPC_BASE_URL', useValue: environment.rpcBaseURL}, {provide: 'RPC_BASE_URL', useValue: environment.rpcBaseURL},
RESTService, RPCService, RESTService, RPCService,
Title,
{
provide: APP_INITIALIZER,
useFactory: initL10n,
deps: [L10nLoader],
multi: true
}
], ],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })

View File

@ -8,5 +8,16 @@
<span class="spacer"></span> <span class="spacer"></span>
<of-notification [notifications]="toolbarHelpers?.notifications"></of-notification> <of-notification [notifications]="toolbarHelpers?.notifications"></of-notification>
<div class="menu-section">
<button mat-icon-button [matMenuTriggerFor]="countryMenu" aria-label="Open x-positioned menu">
<mat-icon>translate</mat-icon>
</button>
<mat-menu xPosition="before" #countryMenu="matMenu" class="before">
<a *ngFor="let item of countryMenuItems" (click)="selectLocale(item.language, item.country, item.currency, item.numberingSystem);"
mat-menu-item>
{{ item.text }}
<mat-icon *ngIf="currentCountry == item.country && currentNumberingSystem == item.numberingSystem">done</mat-icon>
</a>
</mat-menu>
</div>
</mat-toolbar> </mat-toolbar>

View File

@ -1,12 +1,23 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { ToolbarHelpers } from './toolbar.helpers'; import { ToolbarHelpers } from './toolbar.helpers';
import { Title } from '@angular/platform-browser';
import { Direction } from '@angular/cdk/bidi';
import { ISubscription } from 'rxjs/Subscription';
import { LocaleService, TranslationService } from 'angular-l10n';
@Component({ @Component({
selector: 'of-header', selector: 'of-header',
templateUrl: './header.component.html', templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'] styleUrls: ['./header.component.scss']
}) })
export class HeaderComponent implements OnInit { export class HeaderComponent implements OnInit, OnDestroy {
countryMenuItems: any[] = [
{ text: 'United States', language: 'en', country: 'US', currency: 'USD', numberingSystem: 'latn' },
{ text: 'Korea', language: 'kr', country: 'KR', currency: 'KRW', numberingSystem: 'latn' }
];
@Input() sidenav; @Input() sidenav;
@Input() sidebar; @Input() sidebar;
@ -16,9 +27,31 @@ export class HeaderComponent implements OnInit {
searchOpen = false; searchOpen = false;
toolbarHelpers = ToolbarHelpers; toolbarHelpers = ToolbarHelpers;
constructor() { } dir: Direction;
subscription: ISubscription;
constructor(public locale: LocaleService, public translation: TranslationService, public title: Title) { }
ngOnInit() { ngOnInit() {
this.subscription = this.translation.translationChanged().subscribe(
() => { this.title.setTitle(this.translation.translate('App.Title')); }
);
// Initializes direction.
// this.dir = this.getLanguageDirection();
} }
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
// getLanguageDirection(language?: string): Direction {
// return this.locale.getLanguageDirection(language) as Direction;
// }
selectLocale(language: string, country: string, currency: string, numberingSystem: string): void {
this.locale.setDefaultLocale(language, country, '', numberingSystem);
this.locale.setCurrentCurrency(currency);
}
} }

View File

@ -12,12 +12,30 @@ import { SensorItemFilterComponent } from './sensor-item-filter/sensor-item-filt
import { HostSummaryCardComponent } from './host-summary-card/host-summary-card.component'; import { HostSummaryCardComponent } from './host-summary-card/host-summary-card.component';
import { AppSummaryCardComponent } from './app-summary-card/app-summary-card.component'; import { AppSummaryCardComponent } from './app-summary-card/app-summary-card.component';
import {
L10nConfig,
L10nLoader,
LocalizationModule,
ProviderType,
StorageStrategy
} from 'angular-l10n';
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
FlexLayoutModule, FlexLayoutModule
], ],
declarations: [SidebarComponent, HeaderComponent, FooterComponent, MenuItemComponent, SubMenubarComponent, InfoTableComponent, SensorSummaryComponent, SensorItemFilterComponent, HostSummaryCardComponent, AppSummaryCardComponent] declarations: [
SidebarComponent,
HeaderComponent,
FooterComponent,
MenuItemComponent,
SubMenubarComponent,
InfoTableComponent,
SensorSummaryComponent,
SensorItemFilterComponent,
HostSummaryCardComponent,
AppSummaryCardComponent
]
}) })
export class LayoutsModule { } export class LayoutsModule { }

View File

@ -4,7 +4,7 @@
<mat-icon matListIcon iconsmall >{{menu.icon}} </mat-icon> <mat-icon matListIcon iconsmall >{{menu.icon}} </mat-icon>
<h3 matLine *ngIf="!iconOnly">{{ menu.name }} </h3> <h3 matLine *ngIf="!iconOnly" l10nTranslate>{{ menu.name }} </h3>
<mat-chip-list *ngIf="menu?.chip && !iconOnly"> <mat-chip-list *ngIf="menu?.chip && !iconOnly">
<mat-chip >{{menu?.chip?.value}} </mat-chip> <mat-chip >{{menu?.chip?.value}} </mat-chip>
</mat-chip-list> </mat-chip-list>
@ -13,7 +13,7 @@
</mat-list-item> </mat-list-item>
<mat-list-item *ngIf = "menu.link!=false" (click)="menu.open = !menu.open" [routerLink]="[menu.link]"> <mat-list-item *ngIf = "menu.link!=false" (click)="menu.open = !menu.open" [routerLink]="[menu.link]">
<mat-icon matListIcon iconsmall >{{menu.icon}} </mat-icon> <mat-icon matListIcon iconsmall >{{menu.icon}} </mat-icon>
<h3 matLine *ngIf="!iconOnly">{{ menu.name }} </h3> <h3 matLine *ngIf="!iconOnly" l10nTranslate>{{ menu.name }} </h3>
</mat-list-item> </mat-list-item>
<of-menu-item *ngFor="let submenu of menu?.sub" [menu]="submenu" [iconOnly]="iconOnly" [secondaryMenu]="true"> </of-menu-item> <of-menu-item *ngFor="let submenu of menu?.sub" [menu]="submenu" [iconOnly]="iconOnly" [secondaryMenu]="true"> </of-menu-item>
</mat-nav-list> </mat-nav-list>

View File

@ -1,5 +1,7 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { Language } from 'angular-l10n';
@Component({ @Component({
selector: 'of-menu-item', selector: 'of-menu-item',
templateUrl: './menu-item.component.html', templateUrl: './menu-item.component.html',
@ -10,6 +12,7 @@ export class MenuItemComponent implements OnInit {
@Input() menu; @Input() menu;
@Input() iconOnly: boolean; @Input() iconOnly: boolean;
@Input() secondaryMenu = false; @Input() secondaryMenu = false;
@Language() lang: string;
constructor() { } constructor() { }

View File

@ -1,39 +1,39 @@
export const menus = [ export const menus = [
{ {
'name': 'Home', 'name': 'App.Home',
'icon': 'home', 'icon': 'home',
'link': '/home', 'link': '/home',
'open': true, 'open': true,
}, },
{ {
'name': 'Infra', 'name': 'App.Infra',
'icon': 'widgets', 'icon': 'widgets',
'link': false, 'link': false,
'open': false, 'open': false,
'sub': [ 'sub': [
{ {
'name': 'Map', 'name': 'App.Map',
'link': '/map', 'link': '/map',
'icon': 'indeterminate_check_box', 'icon': 'indeterminate_check_box',
'chip': false, 'chip': false,
'open': false, 'open': false,
}, },
{ {
'name': 'Sensors', 'name': 'App.Sensors',
'link': '/sensors', 'link': '/sensors',
'icon': 'indeterminate_check_box', 'icon': 'indeterminate_check_box',
'chip': false, 'chip': false,
'open': false, 'open': false,
}, },
{ {
'name': 'SensorSetting', 'name': 'App.SensorSetting',
'link': '/sensor-setting', 'link': '/sensor-setting',
'icon': 'indeterminate_check_box', 'icon': 'indeterminate_check_box',
'chip': false, 'chip': false,
'open': false, 'open': false,
}, },
{ {
'name': 'Probes', 'name': 'App.Probes',
'link': '/probes', 'link': '/probes',
'icon': 'indeterminate_check_box', 'icon': 'indeterminate_check_box',
'chip': false, 'chip': false,
@ -42,20 +42,20 @@ export const menus = [
] ]
}, },
{ {
'name': 'Monitor', 'name': 'App.Monitor',
'icon': 'widgets', 'icon': 'widgets',
'link': false, 'link': false,
'open': false, 'open': false,
'sub': [ 'sub': [
{ {
'name': 'Overview', 'name': 'App.Overview',
'link': '/overview', 'link': '/overview',
'icon': 'indeterminate_check_box', 'icon': 'indeterminate_check_box',
'chip': false, 'chip': false,
'open': false, 'open': false,
}, },
{ {
'name': 'Dashboards', 'name': 'App.Dashboards',
'link': '/dashboard', 'link': '/dashboard',
'icon': 'indeterminate_check_box', 'icon': 'indeterminate_check_box',
'chip': { 'value': 3, 'color': 'accent'}, 'chip': { 'value': 3, 'color': 'accent'},
@ -64,25 +64,25 @@ export const menus = [
] ]
}, },
{ {
'name': 'Alert', 'name': 'App.Alert',
'icon': 'warning', 'icon': 'warning',
'link': '', 'link': '',
'open': true, 'open': true,
}, },
{ {
'name': 'Report', 'name': 'App.Report',
'icon': '', 'icon': '',
'link': '', 'link': '',
'open': true, 'open': true,
}, },
{ {
'name': 'Log', 'name': 'App.Log',
'icon': '', 'icon': '',
'link': '', 'link': '',
'open': true, 'open': true,
}, },
{ {
'name': 'Setting', 'name': 'App.Setting',
'icon': '', 'icon': '',
'link': '/auth/signin', 'link': '/auth/signin',
'open': true, 'open': true,

View File

@ -1,5 +1,6 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { menus } from './menu-element'; import { menus } from './menu-element';
import { Language } from 'angular-l10n';
@Component({ @Component({
selector: 'of-sidebar', selector: 'of-sidebar',
@ -7,7 +8,7 @@ import { menus } from './menu-element';
styleUrls: ['./sidebar.component.scss'] styleUrls: ['./sidebar.component.scss']
}) })
export class SidebarComponent implements OnInit { export class SidebarComponent implements OnInit {
@Language() lang: string;
@Input() iconOnly = false; @Input() iconOnly = false;
public menus = menus; public menus = menus;

View File

@ -1,6 +1,6 @@
<nav mat-tab-nav-bar> <nav mat-tab-nav-bar>
<a mat-tab-link *ngFor="let tab of tabs" [routerLink]="tab.path" routerLinkActive #rla="routerLinkActive" [routerLinkActiveOptions]="{exact: true}" <a mat-tab-link *ngFor="let tab of tabs" [routerLink]="tab.path" routerLinkActive #rla="routerLinkActive" [routerLinkActiveOptions]="{exact: true}"
[active]="rla.isActive"> [active]="rla.isActive" l10nTranslate>
{{ tab.label }} {{ tab.label }}
</a> </a>
</nav> </nav>

View File

@ -1,13 +1,15 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { Language } from 'angular-l10n';
@Component({ @Component({
selector: 'of-sub-menubar', selector: 'of-sub-menubar',
templateUrl: './sub-menubar.component.html', templateUrl: './sub-menubar.component.html',
styleUrls: ['./sub-menubar.component.scss'] styleUrls: ['./sub-menubar.component.scss']
}) })
export class SubMenubarComponent implements OnInit { export class SubMenubarComponent implements OnInit {
@Language() lang: string;
@Input() tabs: any; @Input() tabs: any;
constructor(public router: Router) { } constructor(public router: Router) { }

View File

@ -8,7 +8,7 @@ import { RouterModule } from '@angular/router';
imports: [ imports: [
CommonModule, CommonModule,
MaterialModule, MaterialModule,
RouterModule, RouterModule
], ],
declarations: [ declarations: [
SubMenubarComponent, SubMenubarComponent,

View File

@ -1,4 +1,5 @@
import { NgModule } from '@angular/core'; import { NgModule, APP_INITIALIZER} from '@angular/core';
import { Title } from '@angular/platform-browser';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { PagesComponent } from './pages.component'; import { PagesComponent } from './pages.component';
import { PagesRoutingModule } from './pages-routing.module'; import { PagesRoutingModule } from './pages-routing.module';
@ -15,6 +16,23 @@ import {
} from 'ngx-perfect-scrollbar'; } from 'ngx-perfect-scrollbar';
import { NotificationModule } from 'packages/notification/notification.module'; import { NotificationModule } from 'packages/notification/notification.module';
import {
L10nConfig,
L10nLoader,
LocalizationModule,
ProviderType
} from 'angular-l10n';
const l10nConfig: L10nConfig = {
translation: {
providers: [
{ type: ProviderType.Static, prefix: './assets/translations/of-' }
],
composedKeySeparator: '.',
missingValue: 'No key'
}
};
const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = { const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
suppressScrollX: true suppressScrollX: true
}; };
@ -28,6 +46,7 @@ const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
MaterialModule, MaterialModule,
PerfectScrollbarModule, PerfectScrollbarModule,
NotificationModule, NotificationModule,
LocalizationModule.forChild(l10nConfig)
], ],
declarations: [ declarations: [
PagesComponent, PagesComponent,
@ -43,4 +62,8 @@ const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
} }
], ],
}) })
export class PagesModule { } export class PagesModule {
constructor(public l10nLoader: L10nLoader) {
this.l10nLoader.load();
}
}

View File

@ -0,0 +1,17 @@
{
"App": {
"Title": "overFlow",
"Subtitle": "It's a small world",
"Home": "Home",
"Map": "Map",
"Sensors": "Sensors",
"SensorSetting": "SensorSetting",
"Probes": "Probes",
"Monitor": "Monitor",
"Overview": "Overview",
"Dashboards": "Dashboards",
"Alert": "Alert",
"Report": "Report",
"Log": "Log"
}
}

View File

@ -0,0 +1,18 @@
{
"App": {
"Title": "오버플로우",
"Subtitle": "It's a small world",
"Home": "홈",
"Infra": "인프라",
"Map": "맵",
"Sensors": "센서",
"SensorSetting": "센서설정",
"Probes": "프로브",
"Monitor": "모니터",
"Overview": "오버뷰",
"Dashboards": "대시보드",
"Alert": "알림",
"Report": "리포트",
"Log": "기록"
}
}

View File

@ -17,7 +17,7 @@
</head> </head>
<body> <body>
<of-root></of-root> <of-root #root="dir" [dir]="dir" fullscreen></of-root>
<div class="loader-container"> <div class="loader-container">
<div class="spinner"> <div class="spinner">