Add translation module and add i18n strings for initial pages (CC-57)

pull/46/head
HardiReady 2018-10-02 10:57:45 +02:00
parent 4c781dd101
commit 0f37c06fc6
7 changed files with 111 additions and 45 deletions

View File

@ -12,39 +12,39 @@
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li routerLinkActive="active"> <li routerLinkActive="active">
<a href="https://www.opt4.net/dashboard" class="link">Zum Forum</a> <a href="https://www.opt4.net/dashboard" class="link">{{'navigation.top.board' | translate}}</a>
</li> </li>
<li routerLinkActive="active"> <li routerLinkActive="active">
<a routerLink='{{config.overviewPath}}' class="link">Armeeübersicht</a> <a routerLink='{{config.overviewPath}}' class="link">{{'navigation.top.overview' | translate}}</a>
</li> </li>
<li routerLinkActive="active"> <li routerLinkActive="active">
<a [routerLink]="[config.publicPath.concat('/').concat(config.rankPath)]" class="link">Ränge</a> <a [routerLink]="[config.publicPath.concat('/').concat(config.rankPath)]" class="link">{{'navigation.top.ranks' | translate}}</a>
</li> </li>
<li routerLinkActive="active"> <li routerLinkActive="active">
<a [routerLink]="[config.publicPath.concat('/').concat(config.decorationPath)]" class="link">Auszeichnungen</a> <a [routerLink]="[config.publicPath.concat('/').concat(config.decorationPath)]" class="link">{{'navigation.top.decorations' | translate}}</a>
</li> </li>
<li routerLinkActive="active"> <li routerLinkActive="active">
<a routerLink='{{config.statsPath}}' class="link">Statistiken</a> <a routerLink='{{config.statsPath}}' class="link">{{'navigation.top.statistics' | translate}}</a>
</li> </li>
<li *ngIf="loginService.hasPermission(2)" <li *ngIf="loginService.hasPermission(2)"
class="dropdown"> class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false"> aria-expanded="false">
Verwaltung {{'navigation.top.management' | translate}}57
<span class="caret"></span> <span class="caret"></span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li routerLinkActive="active"> <li routerLinkActive="active">
<a routerLink='{{config.userPath}}' class="link">Teilnehmer</a> <a routerLink='{{config.userPath}}' class="link">{{'navigation.top.management.users' | translate}}</a>
</li> </li>
<li routerLinkActive="active"> <li routerLinkActive="active">
<a routerLink='{{config.squadPath}}' class="link">Squads</a> <a routerLink='{{config.squadPath}}' class="link">{{'navigation.top.management.squads' | translate}}</a>
</li> </li>
<li routerLinkActive="active"> <li routerLinkActive="active">
<a routerLink='{{config.decorationPath}}' class="link">Auszeichnungen</a> <a routerLink='{{config.decorationPath}}' class="link">{{'navigation.top.management.decorations' | translate}}</a>
</li> </li>
<li routerLinkActive="active"> <li routerLinkActive="active">
<a routerLink='{{config.rankPath}}' class="link">Ränge</a> <a routerLink='{{config.rankPath}}' class="link">{{'navigation.top.management.ranks' | translate}}</a>
</li> </li>
</ul> </ul>
</li> </li>
@ -52,18 +52,18 @@
class="dropdown"> class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false"> aria-expanded="false">
Beantragen {{'navigation.top.request' | translate}}
<span class="caret"></span> <span class="caret"></span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li> <li>
<a routerLink="{{config.request}}/{{config.sqlDashboardPath}}">Offene Anträge</a> <a routerLink="{{config.request}}/{{config.sqlDashboardPath}}">{{'navigation.top.request.open' | translate}}</a>
</li> </li>
<li> <li>
<a routerLink="{{config.request}}/{{config.requestPromotionPath}}">Beförderung</a> <a routerLink="{{config.request}}/{{config.requestPromotionPath}}">{{'navigation.top.request.promotion' | translate}}</a>
</li> </li>
<li> <li>
<a routerLink="{{config.request}}/{{config.requestAwardPath}}">Orden/ Auszeichnung</a> <a routerLink="{{config.request}}/{{config.requestAwardPath}}">{{'navigation.top.request.award' | translate}}</a>
</li> </li>
</ul> </ul>
</li> </li>
@ -72,31 +72,31 @@
[ngClass]="{'unprocessed': promotionService.hasUnprocessedPromotion || awardingService.hasUnprocessedAwards}" [ngClass]="{'unprocessed': promotionService.hasUnprocessedPromotion || awardingService.hasUnprocessedAwards}"
class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false"> aria-expanded="false">
Anträge {{'navigation.top.request.manage' | translate}}
<span class="caret"></span> <span class="caret"></span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li> <li>
<a [ngClass]="{'unprocessed-child': promotionService.hasUnprocessedPromotion}" <a [ngClass]="{'unprocessed-child': promotionService.hasUnprocessedPromotion}"
routerLink="{{config.request}}/{{config.confirmPromotionPath}}">Beförderung</a> routerLink="{{config.request}}/{{config.confirmPromotionPath}}">{{'navigation.top.request.promotion' | translate}}</a>
</li> </li>
<li> <li>
<a [ngClass]="{'unprocessed-child': awardingService.hasUnprocessedAwards}" <a [ngClass]="{'unprocessed-child': awardingService.hasUnprocessedAwards}"
routerLink="{{config.request}}/{{config.confirmAwardPath}}">Orden/ Auszeichnung</a> routerLink="{{config.request}}/{{config.confirmAwardPath}}">{{'navigation.top.request.award' | translate}}</a>
</li> </li>
</ul> </ul>
</li> </li>
</ul> </ul>
<ul class="nav navbar-nav" style="float: right"> <ul class="nav navbar-nav pull-right">
<li *ngIf="loginService.hasPermission(4)" routerLinkActive="active"> <li *ngIf="loginService.hasPermission(4)" routerLinkActive="active">
<a routerLink='{{config.adminPanelPath}}' class="link">Admin Panel</a> <a routerLink='{{config.adminPanelPath}}' class="link">{{'navigation.top.admin' | translate}}</a>
</li> </li>
<li *ngIf="loginService.isLoggedIn()" class="link" style="cursor: pointer"> <li *ngIf="loginService.isLoggedIn()" class="link" style="cursor: pointer">
<a (click)="logout()">Abmelden</a> <a (click)="logout()">{{'navigation.top.logout' | translate}}</a>
</li> </li>
<li *ngIf="!loginService.isLoggedIn()" routerLinkActive="active"> <li *ngIf="!loginService.isLoggedIn()" routerLinkActive="active">
<a routerLink='{{config.loginPath}}' class="link">Login</a> <a routerLink='{{config.loginPath}}' class="link">{{'navigation.top.login' | translate}}</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -122,7 +122,7 @@
mat-mini-fab mat-mini-fab
id="scrollTopBtn" id="scrollTopBtn"
*ngIf="scrollTopVisible" *ngIf="scrollTopVisible"
matTooltip="Zum Seitenanfang" matTooltip="{{'navigation.button.scroll.top' | translate}}"
(click)="scrollToTop()"> (click)="scrollToTop()">
<mat-icon svgIcon="arrow-up"></mat-icon> <mat-icon svgIcon="arrow-up"></mat-icon>
</button> </button>

View File

@ -8,6 +8,7 @@ import {DOCUMENT} from '@angular/common';
import {DomSanitizer} from '@angular/platform-browser'; import {DomSanitizer} from '@angular/platform-browser';
import {MatIconRegistry} from '@angular/material'; import {MatIconRegistry} from '@angular/material';
import {SpinnerService} from './services/user-interface/spinner/spinner.service'; import {SpinnerService} from './services/user-interface/spinner/spinner.service';
import {TranslateService} from '@ngx-translate/core';
declare function require(url: string); declare function require(url: string);
@ -64,6 +65,7 @@ export class AppComponent implements OnInit {
private iconRegistry: MatIconRegistry, private iconRegistry: MatIconRegistry,
private sanitizer: DomSanitizer, private sanitizer: DomSanitizer,
private spinnerService: SpinnerService, private spinnerService: SpinnerService,
private translate: TranslateService,
@Inject(DOCUMENT) private document) { @Inject(DOCUMENT) private document) {
this.initMaterialSvgIcons(); this.initMaterialSvgIcons();
@ -85,6 +87,15 @@ export class AppComponent implements OnInit {
}); });
} }
ngOnInit() {
this.translate.setDefaultLang('de');
if (this.loginService.hasPermission(2)) {
const fraction = this.loginService.getCurrentUser().squad.fraction;
this.promotionService.checkUnconfirmedPromotions(fraction);
this.awardingService.checkUnprocessedAwards(fraction);
}
}
toggleSpinner(active) { toggleSpinner(active) {
this.loading = active; this.loading = active;
} }
@ -103,14 +114,6 @@ export class AppComponent implements OnInit {
|| document.documentElement.scrollTop > this.scrollBtnVisibleVal; || document.documentElement.scrollTop > this.scrollBtnVisibleVal;
} }
ngOnInit() {
if (this.loginService.hasPermission(2)) {
const fraction = this.loginService.getCurrentUser().squad.fraction;
this.promotionService.checkUnconfirmedPromotions(fraction);
this.awardingService.checkUnprocessedAwards(fraction);
}
}
logout() { logout() {
this.loginService.logout(); this.loginService.logout();
setTimeout(() => { setTimeout(() => {
@ -122,5 +125,13 @@ export class AppComponent implements OnInit {
this.document.body.scrollTop = 0; // For Safari this.document.body.scrollTop = 0; // For Safari
this.document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera this.document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
} }
// TODO: use!
// private setLanguage(settings: SettingsState) {
// const { language } = settings;
// if (language) {
// this.translate.use(language);
// }
// }
} }

View File

@ -13,7 +13,6 @@ import {RankService} from './services/army-management/rank.service';
import {AppConfig} from './app.config'; import {AppConfig} from './app.config';
import {LoginGuardAdmin, LoginGuardHL, LoginGuardSQL} from './login'; import {LoginGuardAdmin, LoginGuardHL, LoginGuardSQL} from './login';
import {AwardingService} from './services/army-management/awarding.service'; import {AwardingService} from './services/army-management/awarding.service';
import {HttpClient} from './services/http-client';
import {ArmyService} from './services/army-service/army.service'; import {ArmyService} from './services/army-service/army.service';
import {ClipboardModule} from 'ngx-clipboard'; import {ClipboardModule} from 'ngx-clipboard';
import {PromotionService} from './services/army-management/promotion.service'; import {PromotionService} from './services/army-management/promotion.service';
@ -26,10 +25,20 @@ import {SnackBarService} from './services/user-interface/snack-bar/snack-bar.ser
import {HttpClientModule} from '@angular/common/http'; import {HttpClientModule} from '@angular/common/http';
import {SpinnerService} from './services/user-interface/spinner/spinner.service'; import {SpinnerService} from './services/user-interface/spinner/spinner.service';
import {MatSnackBarModule} from '@angular/material'; import {MatSnackBarModule} from '@angular/material';
import {HttpClient} from './services/http-client';
@NgModule({ @NgModule({
imports: [SharedModule, BrowserModule, BrowserAnimationsModule, appRouting, HttpModule, HttpClientModule, imports: [
ClipboardModule, MatSnackBarModule], SharedModule,
BrowserModule,
BrowserAnimationsModule,
appRouting,
HttpModule,
HttpClientModule,
ClipboardModule,
MatSnackBarModule,
],
providers: [ providers: [
HttpClient, HttpClient,
LoginService, LoginService,
@ -53,10 +62,15 @@ import {MatSnackBarModule} from '@angular/material';
SnackBarService, SnackBarService,
SpinnerService, SpinnerService,
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
routingComponents], routingComponents
bootstrap: [AppComponent] ],
bootstrap: [
AppComponent
]
}) })
export class AppModule { export class AppModule {
} }

View File

@ -18,7 +18,7 @@
</div> </div>
<div> <div>
<div class="squad-cell squad-member-count"> <div class="squad-cell squad-member-count">
Mitglieder: {{squad.memberCount}} {{'public army.squad.members' | translate}} {{squad.memberCount}}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,5 +1,5 @@
<div style="width: 1100px; margin:auto; position: relative;"> <div style="width: 1100px; margin:auto; position: relative;">
<h1>Übersicht über alle Spieler, Squads und Armeen</h1> <h1>{{'public.army.headline' | translate}}</h1>
<div class="pull-left army-column"> <div class="pull-left army-column">
<h3 class="army-head" [style.color]="fraction.COLOR_BLUFOR">{{fraction.BLUFOR}}</h3> <h3 class="army-head" [style.color]="fraction.COLOR_BLUFOR">{{fraction.BLUFOR}}</h3>
@ -8,7 +8,7 @@
squadFraction="BLUFOR" squadFraction="BLUFOR"
(memberSelect)="select($event)"> (memberSelect)="select($event)">
</cc-army-squad> </cc-army-squad>
<div class="member-count">Armeemitglieder: {{army[0].memberCount}}</div> <div class="member-count">{{'public.army.members' | translate}} {{army[0].memberCount}}</div>
</div> </div>
<div class="pull-right army-column"> <div class="pull-right army-column">
@ -18,6 +18,6 @@
squadFraction="OPFOR" squadFraction="OPFOR"
(memberSelect)="select($event)"> (memberSelect)="select($event)">
</cc-army-squad> </cc-army-squad>
<div class="member-count">Armeemitglieder: {{army[1].memberCount}}</div> <div class="member-count">{{'public.army.members' | translate}} {{army[1].memberCount}}</div>
</div> </div>
</div> </div>

View File

@ -32,5 +32,4 @@ export class ArmyComponent implements OnInit {
select(memberId) { select(memberId) {
this.router.navigate(['member', memberId], {relativeTo: this.route}); this.router.navigate(['member', memberId], {relativeTo: this.route});
} }
} }

View File

@ -7,13 +7,55 @@ import {SearchFieldComponent} from './common/user-interface/search-field/search-
import {MatButtonToggleModule, MatTooltipModule} from '@angular/material'; import {MatButtonToggleModule, MatTooltipModule} from '@angular/material';
import {MatButtonModule} from '@angular/material/button'; import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon'; import {MatIconModule} from '@angular/material/icon';
import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
import {HttpClient} from '@angular/common/http';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
@NgModule({ @NgModule({
declarations: [ShowErrorComponent, ListFilterComponent, SearchFieldComponent], declarations: [
imports: [CommonModule, FormsModule, ReactiveFormsModule, MatButtonToggleModule, MatButtonModule, MatIconModule, ShowErrorComponent,
MatTooltipModule], ListFilterComponent,
exports: [FormsModule, ReactiveFormsModule, MatButtonToggleModule, MatButtonModule, MatIconModule, ShowErrorComponent, SearchFieldComponent
ListFilterComponent, SearchFieldComponent, MatTooltipModule], ],
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
MatButtonToggleModule,
MatButtonModule,
MatIconModule,
MatTooltipModule,
// 3rd party
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
],
exports: [
FormsModule,
ReactiveFormsModule,
MatButtonToggleModule,
MatButtonModule,
MatIconModule,
ShowErrorComponent,
ListFilterComponent,
SearchFieldComponent,
MatTooltipModule,
TranslateModule],
}) })
export class SharedModule { export class SharedModule {
} }
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(
http,
`/assets/i18n/`,
'.json'
);
}