Add basic language changing functionality
parent
1d46b301f5
commit
8ea5e188a0
|
@ -89,6 +89,21 @@
|
|||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav pull-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
Language
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a (click)="setLanguage('en')">English</a>
|
||||
</li>
|
||||
<li>
|
||||
<a (click)="setLanguage('de')">Deutsch</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li *ngIf="loginService.hasPermission(4)" routerLinkActive="active">
|
||||
<a routerLink='{{config.adminPanelPath}}' class="link">{{'navigation.top.admin' | translate}}</a>
|
||||
</li>
|
||||
|
|
|
@ -9,6 +9,8 @@ import {DomSanitizer} from '@angular/platform-browser';
|
|||
import {MatIconRegistry} from '@angular/material';
|
||||
import {SpinnerService} from './services/user-interface/spinner/spinner.service';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {Language} from './settings/settings-state.model';
|
||||
import {SettingsService} from './services/settings.service';
|
||||
|
||||
declare function require(url: string);
|
||||
|
||||
|
@ -66,6 +68,7 @@ export class AppComponent implements OnInit {
|
|||
private sanitizer: DomSanitizer,
|
||||
private spinnerService: SpinnerService,
|
||||
private translate: TranslateService,
|
||||
private settingsService: SettingsService,
|
||||
@Inject(DOCUMENT) private document) {
|
||||
this.initMaterialSvgIcons();
|
||||
|
||||
|
@ -88,7 +91,7 @@ export class AppComponent implements OnInit {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.translate.setDefaultLang('de');
|
||||
this.settingsService.getLanguage().subscribe((language) => this.translate.setDefaultLang(language));
|
||||
if (this.loginService.hasPermission(2)) {
|
||||
const fraction = this.loginService.getCurrentUser().squad.fraction;
|
||||
this.promotionService.checkUnconfirmedPromotions(fraction);
|
||||
|
@ -126,12 +129,10 @@ export class AppComponent implements OnInit {
|
|||
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);
|
||||
// }
|
||||
// }
|
||||
setLanguage(language: Language) {
|
||||
if (language) {
|
||||
this.settingsService.setLanguage(language);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import {HttpClientModule} from '@angular/common/http';
|
|||
import {SpinnerService} from './services/user-interface/spinner/spinner.service';
|
||||
import {MatSnackBarModule} from '@angular/material';
|
||||
import {HttpClient} from './services/http-client';
|
||||
import {SettingsService} from './services/settings.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -61,6 +62,7 @@ import {HttpClient} from './services/http-client';
|
|||
CookieService,
|
||||
SnackBarService,
|
||||
SpinnerService,
|
||||
SettingsService,
|
||||
],
|
||||
|
||||
declarations: [
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {FormGroup, NgForm} from '@angular/forms';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {SettingsService} from '../../services/settings.service';
|
||||
|
||||
@Component({
|
||||
selector: 'show-error',
|
||||
|
@ -11,7 +12,7 @@ import {TranslateService} from '@ngx-translate/core';
|
|||
</div>
|
||||
</div>`
|
||||
})
|
||||
export class ShowErrorComponent implements OnInit {
|
||||
export class ShowErrorComponent {
|
||||
|
||||
// tslint:disable-next-line:no-input-rename
|
||||
@Input('controlPath') controlPath;
|
||||
|
@ -22,12 +23,10 @@ export class ShowErrorComponent implements OnInit {
|
|||
private form: FormGroup;
|
||||
|
||||
constructor(ngForm: NgForm,
|
||||
private translate: TranslateService) {
|
||||
private translate: TranslateService,
|
||||
private settingsService: SettingsService) {
|
||||
this.form = ngForm.form;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.translate.setDefaultLang('de');
|
||||
this.settingsService.getLanguage().subscribe((language) => this.translate.setDefaultLang(language));
|
||||
}
|
||||
|
||||
get errorMessages(): string[] {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {SettingsService} from '../services/settings.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-manage-root',
|
||||
|
@ -7,7 +8,8 @@ import {TranslateService} from '@ngx-translate/core';
|
|||
styleUrls: ['./manage.component.scss']
|
||||
})
|
||||
export class ManageComponent {
|
||||
constructor(private translate: TranslateService) {
|
||||
this.translate.setDefaultLang('de');
|
||||
constructor(private translate: TranslateService,
|
||||
private settingsService: SettingsService) {
|
||||
this.settingsService.getLanguage().subscribe((language) => this.translate.setDefaultLang(language));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {SettingsService} from '../services/settings.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-public',
|
||||
|
@ -7,7 +8,8 @@ import {TranslateService} from '@ngx-translate/core';
|
|||
styleUrls: ['./public.component.scss']
|
||||
})
|
||||
export class PublicComponent {
|
||||
constructor(private translate: TranslateService) {
|
||||
this.translate.setDefaultLang('de');
|
||||
constructor(private translate: TranslateService,
|
||||
private settingsService: SettingsService) {
|
||||
this.settingsService.getLanguage().subscribe((language) => this.translate.setDefaultLang(language));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<th class="col-sm-1">{{'request.confirm.promotion.table.head.participant' | translate}}</th>
|
||||
<th class="col-sm-1">{{'request.confirm.promotion.table.head.rank.before' | translate}}</th>
|
||||
<th class="col-sm-1">{{'request.confirm.promotion.table.head.rank.after' | translate}}</th>
|
||||
<th class="col-sm-1 ">{{'"request.confirm.promotion.table.head.requester' | translate}}</th>
|
||||
<th class="col-sm-1 ">{{'request.confirm.promotion.table.head.requester' | translate}}</th>
|
||||
<th class="col-sm-1 text-center">{{'request.confirm.promotion.table.head.date' | translate}}</th>
|
||||
<th class="col-sm-1 text-center">{{'request.confirm.promotion.table.head.status' | translate}}</th>
|
||||
<th class="col-sm-2 text-right"></th>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {SettingsService} from '../services/settings.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-request-root',
|
||||
|
@ -7,7 +8,8 @@ import {TranslateService} from '@ngx-translate/core';
|
|||
styleUrls: ['request.component.css']
|
||||
})
|
||||
export class RequestComponent {
|
||||
constructor(private translate: TranslateService) {
|
||||
translate.setDefaultLang('de');
|
||||
constructor(private translate: TranslateService,
|
||||
private settingsService: SettingsService) {
|
||||
this.settingsService.getLanguage().subscribe((language) => this.translate.setDefaultLang(language));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {Observable} from 'rxjs/internal/Observable';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class SettingsService {
|
||||
|
||||
language = new BehaviorSubject<string>('de');
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
setLanguage(language: string) {
|
||||
this.language.next(language);
|
||||
}
|
||||
|
||||
getLanguage(): Observable<string> {
|
||||
return this.language.asObservable();
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ import {Campaign} from '../models/model-interfaces';
|
|||
import {CampaignService} from '../services/logs/campaign.service';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {SettingsService} from '../services/settings.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-stats',
|
||||
|
@ -20,8 +21,9 @@ export class StatisticComponent implements OnInit {
|
|||
constructor(private campaignService: CampaignService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private translate: TranslateService) {
|
||||
this.translate.setDefaultLang('de');
|
||||
private translate: TranslateService,
|
||||
private settingsService: SettingsService) {
|
||||
this.settingsService.getLanguage().subscribe((language) => this.translate.setDefaultLang(language));
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"navigation.top.board": "Zum Forum",
|
||||
"navigation.top.overview": "Armeeübersicht",
|
||||
"navigation.top.ranks": "Ränge",
|
||||
"navigation.top.decorations": "Auszeichnungem",
|
||||
"navigation.top.decorations": "Auszeichnungen",
|
||||
"navigation.top.statistics": "Statistiken",
|
||||
"navigation.top.login": "Login",
|
||||
"navigation.top.logout": "Abmelden",
|
||||
|
|
|
@ -1,2 +1,52 @@
|
|||
{
|
||||
"public.error.message.required": "{{fieldName}} is a required field",
|
||||
"public.error.message.min.length": "{{fieldName}} requires at least {{boundary}} characters",
|
||||
"public.error.message.max.length": "{{fieldName}} is limited to {{boundary}} characters",
|
||||
"public.error.message.email": "Please enter a valid eMail address",
|
||||
"public.error.message.no.user": "The choosen user does not exist",
|
||||
"public.error.message.default": "{{fieldName}} is not valid",
|
||||
"public.common.search.button": "Search",
|
||||
|
||||
"navigation.top.board": "To message board",
|
||||
"navigation.top.overview": "Army Overview",
|
||||
"navigation.top.ranks": "Ranks",
|
||||
"navigation.top.decorations": "Awards",
|
||||
"navigation.top.statistics": "Statistics",
|
||||
"navigation.top.login": "Login",
|
||||
"navigation.top.logout": "Logout",
|
||||
"navigation.top.management": "Manage",
|
||||
"navigation.top.management.users": "Users",
|
||||
"navigation.top.management.squads": "Squads",
|
||||
"navigation.top.management.decorations": "Decorations",
|
||||
"navigation.top.management.ranks": "Ranks",
|
||||
"navigation.top.request": "Request",
|
||||
"navigation.top.request.open": "Open Requests",
|
||||
"navigation.top.request.manage": "Requests",
|
||||
"navigation.top.request.promotion": "Promotion",
|
||||
"navigation.top.request.award": "Medal/ Ribbon",
|
||||
"navigation.top.admin": "Admin Panel",
|
||||
"navigation.button.scroll.top": "Back to top",
|
||||
|
||||
"login.headline": "Login",
|
||||
"login.username": "Username",
|
||||
"login.password": "Password",
|
||||
"login.submit": "Submit",
|
||||
"signup.headline": "Sign Up",
|
||||
"signup.username": "Username",
|
||||
"signup.password": "Password",
|
||||
"signup.secret": "Secret",
|
||||
"signup.secret.placeholder": "Secret text for message comparison",
|
||||
"signup.submit": "Submit",
|
||||
"signup.description": "Dieses Formular nur ausfüllen wenn du einer <b>HL</b> angehörst oder <b>SQL</b> bist. Dabei den Nutzernamen aus dem OPT Forum verwenden! Im Forum eine Nachricht an <a href=\"https://www.opt4.net/dashboard/index.php?conversation-add/&userID=9\" target=\"_blank\">HardiReady</a> senden, in welcher der 'geheime Text' steht, den du bei der Registrierung nutzt.<br> Dabei kann es sich um irgend eine willkürliche Zeichenfolge oder einen Satz handeln - dient nur dem Abgleich. Anschließend wird dein Account aktiviert und du wirst darüber per PN informiert.",
|
||||
|
||||
"public.army.headline": "Overview of all players, squads and armies",
|
||||
"public army.squad.members": "Members:",
|
||||
"public.army.members": "Army Members:",
|
||||
|
||||
"public.army.member.button.back": "Back",
|
||||
"public.army.member.button.copy": "copy",
|
||||
"public.army.member.headline": "Awards of {{name}}",
|
||||
"public.army.member.awards.title": "Title",
|
||||
"public.army.member.awards.reason": "Reason",
|
||||
"public.army.member.awards.date": "Decorated at"
|
||||
}
|
||||
|
|
|
@ -1,86 +1,3 @@
|
|||
{
|
||||
"stats.campaign.manage.edit": "Edit",
|
||||
"stats.campaign.manage.delete": "Delete",
|
||||
"stats.campaign.manage.delete.confirm": "Do you really want to delete the campaign \"{{title}}\"?",
|
||||
"stats.campaign.title.all.time.overview": "All time overview",
|
||||
|
||||
"stats.sidebar.campaign.add": "Add campaign",
|
||||
"stats.sidebar.battle.add": "Add battle",
|
||||
"stats.sidebar.overview": "Overview",
|
||||
"stats.sidebar.highscore": "Highscore",
|
||||
"stats.sidebar.battles": "Battles",
|
||||
"stats.sidebar.battles.battle.from.date": "at",
|
||||
"stats.sidebar.battle.manage.edit": "Edit",
|
||||
"stats.sidebar.battle.manage.delete": "Delete",
|
||||
"stats.sidebar.battle.manage.delete.confirm": "Do you really want to delete the battle \"{{title}}\"?",
|
||||
|
||||
"stats.graph.select.sum.points": "Total Score",
|
||||
"stats.graph.select.battle.points": "Score per Battle",
|
||||
"stats.graph.select.player.count": "Player count",
|
||||
|
||||
"stats.fraction.select.points": "Score",
|
||||
"stats.fraction.select.budget": "Budget",
|
||||
"stats.fraction.select.kills": "Kills",
|
||||
"stats.fraction.select.friendly.fire": "Friendly Fire",
|
||||
"stats.fraction.select.vehicle.kills": "Vehicle Kills",
|
||||
"stats.fraction.select.air.transport": "Air Transport",
|
||||
"stats.fraction.select.revive": "Revive",
|
||||
"stats.fraction.select.stabilize": "Stabilized",
|
||||
"stats.fraction.select.flag": "Flag Possession",
|
||||
|
||||
"stats.player.detail.headline": "Campaign Details - {{name}}",
|
||||
"stats.player.detail.button.back": "Back",
|
||||
"stats.player.detail.kill.death.ratio": "Kill/Death",
|
||||
"stats.player.detail.respawn.death.ratio": "Respawn/Death",
|
||||
"stats.player.detail.graph.average": "Average",
|
||||
|
||||
"stats.scoreboard.standings": "Final Score:",
|
||||
"stats.scoreboard.participants": "Participants:",
|
||||
"stats.scoreboard.show.logs": "Show Logfile",
|
||||
"stats.scoreboard.download.csv": "Download CSV",
|
||||
"stats.scoreboard.tab.scoreboard": "Scoreboard",
|
||||
"stats.scoreboard.tab.fractions": "Fractions",
|
||||
"stats.scoreboard.tab.player": "Player",
|
||||
"stats.scoreboard.fraction.filter.all": "All",
|
||||
"stats.scoreboard.header.player": "Player",
|
||||
"stats.scoreboard.header.fraction": "Fraction",
|
||||
"stats.scoreboard.header.kill": "Kills",
|
||||
"stats.scoreboard.header.friendly.fire": "Friendly Fire",
|
||||
"stats.scoreboard.header.revive": "Revive",
|
||||
"stats.scoreboard.header.capture": "Flag Capture",
|
||||
"stats.scoreboard.header.vehicle.light": "Vehicle (Light)",
|
||||
"stats.scoreboard.header.vehicle.heavy": "Vehicle (Heavy)",
|
||||
"stats.scoreboard.header.vehicle.air": "Vehicle (Air)",
|
||||
"stats.scoreboard.header.death": "Death",
|
||||
"stats.scoreboard.header.respawn": "Respawn",
|
||||
"stats.scoreboard.button.detail": "Campaign statistics for {{name}}",
|
||||
|
||||
"stats.highscore.filter.placholder": "Player Name (separate multiple using '&')",
|
||||
"stats.highscore.filter.button": "Filter",
|
||||
"stats.highscore.header.name": "Name",
|
||||
|
||||
"stats.war.submit.headline.new": "Add new battöe",
|
||||
"stats.war.submit.headline.edit": "Edit battle",
|
||||
"stats.war.submit.title": "Title",
|
||||
"stats.war.submit.campaign": "Campaign",
|
||||
"stats.war.submit.logfile": "Logfile",
|
||||
"stats.war.submit.points": "Score",
|
||||
"stats.war.submit.final.budget": "Final budget",
|
||||
"stats.war.submit.button.submit": "Submit",
|
||||
"stats.war.submit.button.cancel": "Cancel",
|
||||
"stats.war.submit.error.file.format": "Logfile requires RPT, LOG or TXT format",
|
||||
|
||||
"stats.campaign.submit.headline.new": "Add new campaign",
|
||||
"stats.campaign.submit.headline.edit": "Edit campaign",
|
||||
"stats.campaign.submit.title": "Title",
|
||||
"stats.campaign.submit.button.submit": "Submit",
|
||||
"stats.campaign.submit.button.cancel": "Cancel",
|
||||
|
||||
"public.error.message.required": "{{fieldName}} is a required field",
|
||||
"public.error.message.min.length": "{{fieldName}} requires at least {{boundary}} characters",
|
||||
"public.error.message.max.length": "{{fieldName}} is limited to {{boundary}} characters",
|
||||
"public.error.message.email": "Please enter a valid eMail address",
|
||||
"public.error.message.no.user": "The choosen user does not exist",
|
||||
"public.error.message.default": "{{fieldName}} is not valid",
|
||||
"public.common.search.button": "Search"
|
||||
}
|
||||
|
|
|
@ -1,3 +1,86 @@
|
|||
{
|
||||
"public.error.message.required": "{{fieldName}} is a required field",
|
||||
"public.error.message.min.length": "{{fieldName}} requires at least {{boundary}} characters",
|
||||
"public.error.message.max.length": "{{fieldName}} is limited to {{boundary}} characters",
|
||||
"public.error.message.email": "Please enter a valid eMail address",
|
||||
"public.error.message.no.user": "The choosen user does not exist",
|
||||
"public.error.message.default": "{{fieldName}} is not valid",
|
||||
"public.common.search.button": "Search",
|
||||
|
||||
"stats.campaign.manage.edit": "Edit",
|
||||
"stats.campaign.manage.delete": "Delete",
|
||||
"stats.campaign.manage.delete.confirm": "Do you really want to delete the campaign \"{{title}}\"?",
|
||||
"stats.campaign.title.all.time.overview": "All time overview",
|
||||
|
||||
"stats.sidebar.campaign.add": "Add campaign",
|
||||
"stats.sidebar.battle.add": "Add battle",
|
||||
"stats.sidebar.overview": "Overview",
|
||||
"stats.sidebar.highscore": "Highscore",
|
||||
"stats.sidebar.battles": "Battles",
|
||||
"stats.sidebar.battles.battle.from.date": "at",
|
||||
"stats.sidebar.battle.manage.edit": "Edit",
|
||||
"stats.sidebar.battle.manage.delete": "Delete",
|
||||
"stats.sidebar.battle.manage.delete.confirm": "Do you really want to delete the battle \"{{title}}\"?",
|
||||
|
||||
"stats.graph.select.sum.points": "Total Score",
|
||||
"stats.graph.select.battle.points": "Score per Battle",
|
||||
"stats.graph.select.player.count": "Player count",
|
||||
|
||||
"stats.fraction.select.points": "Score",
|
||||
"stats.fraction.select.budget": "Budget",
|
||||
"stats.fraction.select.kills": "Kills",
|
||||
"stats.fraction.select.friendly.fire": "Friendly Fire",
|
||||
"stats.fraction.select.vehicle.kills": "Vehicle Kills",
|
||||
"stats.fraction.select.air.transport": "Air Transport",
|
||||
"stats.fraction.select.revive": "Revive",
|
||||
"stats.fraction.select.stabilize": "Stabilized",
|
||||
"stats.fraction.select.flag": "Flag Possession",
|
||||
|
||||
"stats.player.detail.headline": "Campaign Details - {{name}}",
|
||||
"stats.player.detail.button.back": "Back",
|
||||
"stats.player.detail.kill.death.ratio": "Kill/Death",
|
||||
"stats.player.detail.respawn.death.ratio": "Respawn/Death",
|
||||
"stats.player.detail.graph.average": "Average",
|
||||
|
||||
"stats.scoreboard.standings": "Final Score:",
|
||||
"stats.scoreboard.participants": "Participants:",
|
||||
"stats.scoreboard.show.logs": "Show Logfile",
|
||||
"stats.scoreboard.download.csv": "Download CSV",
|
||||
"stats.scoreboard.tab.scoreboard": "Scoreboard",
|
||||
"stats.scoreboard.tab.fractions": "Fractions",
|
||||
"stats.scoreboard.tab.player": "Player",
|
||||
"stats.scoreboard.fraction.filter.all": "All",
|
||||
"stats.scoreboard.header.player": "Player",
|
||||
"stats.scoreboard.header.fraction": "Fraction",
|
||||
"stats.scoreboard.header.kill": "Kills",
|
||||
"stats.scoreboard.header.friendly.fire": "Friendly Fire",
|
||||
"stats.scoreboard.header.revive": "Revive",
|
||||
"stats.scoreboard.header.capture": "Flag Capture",
|
||||
"stats.scoreboard.header.vehicle.light": "Vehicle (Light)",
|
||||
"stats.scoreboard.header.vehicle.heavy": "Vehicle (Heavy)",
|
||||
"stats.scoreboard.header.vehicle.air": "Vehicle (Air)",
|
||||
"stats.scoreboard.header.death": "Death",
|
||||
"stats.scoreboard.header.respawn": "Respawn",
|
||||
"stats.scoreboard.button.detail": "Campaign statistics for {{name}}",
|
||||
|
||||
"stats.highscore.filter.placholder": "Player Name (separate multiple using '&')",
|
||||
"stats.highscore.filter.button": "Filter",
|
||||
"stats.highscore.header.name": "Name",
|
||||
|
||||
"stats.war.submit.headline.new": "Add new battöe",
|
||||
"stats.war.submit.headline.edit": "Edit battle",
|
||||
"stats.war.submit.title": "Title",
|
||||
"stats.war.submit.campaign": "Campaign",
|
||||
"stats.war.submit.logfile": "Logfile",
|
||||
"stats.war.submit.points": "Score",
|
||||
"stats.war.submit.final.budget": "Final budget",
|
||||
"stats.war.submit.button.submit": "Submit",
|
||||
"stats.war.submit.button.cancel": "Cancel",
|
||||
"stats.war.submit.error.file.format": "Logfile requires RPT, LOG or TXT format",
|
||||
|
||||
"stats.campaign.submit.headline.new": "Add new campaign",
|
||||
"stats.campaign.submit.headline.edit": "Edit campaign",
|
||||
"stats.campaign.submit.title": "Title",
|
||||
"stats.campaign.submit.button.submit": "Submit",
|
||||
"stats.campaign.submit.button.cancel": "Cancel"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue