profile + i18n
This commit is contained in:
@@ -19,6 +19,7 @@ import {VoucherComponent} from './pages/account/voucher/voucher.component';
|
||||
import {SecurityComponent} from './pages/account/security/security.component';
|
||||
import {UnavailableComponent} from './pages/unavailable/unavailable.component';
|
||||
import {NotfoundComponent} from './pages/notfound/notfound.component';
|
||||
import {UserComponent} from './pages/user/user.component'
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', redirectTo: "/account/info", pathMatch: 'full'},
|
||||
@@ -44,7 +45,8 @@ const routes: Routes = [
|
||||
{path: 'register', component: RegisterComponent, canActivate: [AnonymousGuard]},
|
||||
{path: 'tokens', component: TokensComponent, canActivate: [AuthGuard]},
|
||||
{path: 'unavailable', component: UnavailableComponent},
|
||||
{path: '**', component: NotfoundComponent, pathMatch: 'full'},
|
||||
{path: 'p/:username', component: UserComponent, canActivate: [AuthUpdateGuard]},
|
||||
{path: '**', component: NotfoundComponent, pathMatch: 'full', canActivate: [AuthUpdateGuard]},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -21,6 +21,11 @@ export class AppComponent {
|
||||
auth;
|
||||
|
||||
constructor(private i18n: I18nService, private authService: AuthService, private router: Router, private iconRegistry: MatIconRegistry, private sanitizer: DomSanitizer, private _adapter: DateAdapter<any>) {
|
||||
iconRegistry.addSvgIcon('logo', sanitizer.bypassSecurityTrustResourceUrl('assets/icons/logo.svg'));
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
this.currentLocale = this.i18n.getLocale();
|
||||
this.locales = this.i18n.getLocales();
|
||||
this.authService.auth.subscribe(data => {
|
||||
@@ -29,10 +34,6 @@ export class AppComponent {
|
||||
|
||||
this._adapter.setLocale(this.currentLocale);
|
||||
|
||||
iconRegistry.addSvgIcon('logo', sanitizer.bypassSecurityTrustResourceUrl('assets/icons/logo.svg'));
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
if(width < 768) {
|
||||
this.opened = false;
|
||||
|
||||
@@ -33,13 +33,15 @@ import {UsernameDialog} from './pages/register/username-dialog/username.dialog';
|
||||
import {UnavailableComponent} from './pages/unavailable/unavailable.component';
|
||||
import {NotfoundComponent} from './pages/notfound/notfound.component';
|
||||
import {HtmlComponent} from './utils/html/html.component';
|
||||
import {ConfirmDialog} from './ui/confirm/confirm.component'
|
||||
import {UserComponent} from './pages/user/user.component'
|
||||
|
||||
|
||||
import {I18nService} from './services/i18n.service';
|
||||
|
||||
|
||||
export function init_app(i18n: I18nService) {
|
||||
return () => i18n.fetch(i18n.getLocale()).then(response => {}, error => {});
|
||||
return () => i18n.fetch().then(response => {}, error => {});
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@@ -81,7 +83,9 @@ export class XhrInterceptor implements HttpInterceptor {
|
||||
UsernameDialog,
|
||||
UnavailableComponent,
|
||||
NotfoundComponent,
|
||||
HtmlComponent
|
||||
HtmlComponent,
|
||||
ConfirmDialog,
|
||||
UserComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<br>
|
||||
<mat-progress-bar *ngIf="!success && !error" mode="indeterminate"></mat-progress-bar>
|
||||
|
||||
<div *ngIf="success">
|
||||
<h3>{{username}}</h3>
|
||||
<app-profilefields [profileFields]="profileFields"></app-profilefields>
|
||||
</div>
|
||||
|
||||
<mat-card *ngIf="error">
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{error.status}}</mat-card-title>
|
||||
<mat-card-subtitle>{{'user.unavailable' | i18n}}</mat-card-subtitle>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>
|
||||
{{'user.unavailable.text' | i18n}}
|
||||
</p>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
@@ -0,0 +1,3 @@
|
||||
h3 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UserComponent } from './user.component';
|
||||
|
||||
describe('UserComponent', () => {
|
||||
let component: UserComponent;
|
||||
let fixture: ComponentFixture<UserComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ UserComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(UserComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
|
||||
import {ActivatedRoute, Router, ParamMap} from '@angular/router';
|
||||
|
||||
import {ProfileService} from '../../services/profile.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user',
|
||||
templateUrl: './user.component.html',
|
||||
styleUrls: ['./user.component.scss']
|
||||
})
|
||||
export class UserComponent implements OnInit {
|
||||
|
||||
username;
|
||||
profileFields = [];
|
||||
error = false;
|
||||
success = false;
|
||||
|
||||
constructor(
|
||||
private profileService: ProfileService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.username = this.route.snapshot.paramMap.get('username');
|
||||
this.profileService.getAllForUser(this.username).subscribe((data: any) => {
|
||||
this.profileFields = data;
|
||||
this.success = true;
|
||||
}, error => {
|
||||
this.error = error;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,35 +1,18 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { isEmpty } from 'rxjs/operators';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class I18nService {
|
||||
|
||||
locale: String;
|
||||
locales = ["de-informal"];
|
||||
locale: string;
|
||||
locales : any = ["de-informal"];
|
||||
i18n: any;
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
let browserLocale = navigator.language;
|
||||
|
||||
if (browserLocale.indexOf("-") != -1) {
|
||||
browserLocale = browserLocale.split("-")[0];
|
||||
}
|
||||
|
||||
let locale = localStorage.getItem("bstly.locale") || browserLocale || this.locales[0];
|
||||
|
||||
if (locale == 'de') {
|
||||
locale = 'de-informal';
|
||||
}
|
||||
|
||||
if (this.locales.indexOf(locale) == -1) {
|
||||
locale = this.locales[0];
|
||||
}
|
||||
|
||||
|
||||
this.setLocale(locale);
|
||||
|
||||
}
|
||||
|
||||
getLocales() {
|
||||
@@ -44,25 +27,44 @@ export class I18nService {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
async fetch(locale) {
|
||||
this.i18n = await this.http.get("./assets/i18n/" + locale + ".json").toPromise();
|
||||
async fetch() {let browserLocale = navigator.language;
|
||||
|
||||
if(browserLocale.indexOf("-") != -1) {
|
||||
browserLocale = browserLocale.split("-")[0];
|
||||
}
|
||||
|
||||
let locale = localStorage.getItem("bstly.locale") || browserLocale || this.locales[0];
|
||||
|
||||
if(locale == 'de') {
|
||||
locale = 'de-informal';
|
||||
}
|
||||
|
||||
this.locales = await this.http.get(environment.apiUrl + "/i18n").toPromise();
|
||||
|
||||
if(this.locales.indexOf(locale) == -1) {
|
||||
locale = this.locales[0];
|
||||
}
|
||||
|
||||
this.i18n = await this.http.get(environment.apiUrl + "/i18n/" + locale).toPromise();
|
||||
|
||||
this.setLocale(locale);
|
||||
}
|
||||
|
||||
get(key, args: any[]): String {
|
||||
get(key, args: string[]): string {
|
||||
return this.getInternal(key, args, this.i18n);
|
||||
}
|
||||
|
||||
getInternal(key, args: any[], from): String {
|
||||
if (!from) {
|
||||
getInternal(key, args: string[], from): string {
|
||||
if(!from) {
|
||||
return key;
|
||||
} else if (from[key]) {
|
||||
if (from[key]["."]) {
|
||||
} else if(from[key]) {
|
||||
if(from[key]["."]) {
|
||||
return this.insertArguments(from[key]["."], args);
|
||||
}
|
||||
return this.insertArguments(from[key], args);
|
||||
} else {
|
||||
let keys = key.split(".");
|
||||
if (from[keys[0]]) {
|
||||
if(from[keys[0]]) {
|
||||
key = keys.slice(1, keys.length).join(".");
|
||||
return this.getInternal(key, args, from[keys[0]])
|
||||
}
|
||||
@@ -71,10 +73,10 @@ export class I18nService {
|
||||
return key;
|
||||
}
|
||||
|
||||
insertArguments(label: String, args: any[]) {
|
||||
if (args) {
|
||||
for (let index in args) {
|
||||
label = label.replace(`{${index}}`, args[index]);
|
||||
insertArguments(label: string, args: string[]) {
|
||||
if(args) {
|
||||
for(let index in args) {
|
||||
label = label.replace(`{${index}}`, this.get(args[index], []));
|
||||
}
|
||||
}
|
||||
return label;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<mat-dialog-content>
|
||||
{{text}}
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
|
||||
<button mat-raised-button [mat-dialog-close]="true" color="accent">{{'confirm' | i18n}}</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -0,0 +1,3 @@
|
||||
mat-form-field {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import {Component, Inject} from '@angular/core';
|
||||
import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
||||
import {I18nService} from '../../services/i18n.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'confirm.component.html',
|
||||
styleUrls: ['./confirm.component.scss']
|
||||
})
|
||||
export class ConfirmDialog {
|
||||
|
||||
|
||||
text;
|
||||
|
||||
constructor(private i18nService: I18nService,
|
||||
public dialogRef: MatDialogRef<ConfirmDialog>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any) {
|
||||
this.text = i18nService.get(data.label, data.args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h1 mat-dialog-title></h1>
|
||||
<h1 mat-dialog-title>{{'profileField.name.' + profileField.name | i18n}}</h1>
|
||||
<mat-dialog-content>
|
||||
<pre>
|
||||
{{profileField.blob}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h1 mat-dialog-title></h1>
|
||||
<h1 mat-dialog-title>{{'profileField.name.' + profileField.name | i18n}}</h1>
|
||||
<mat-dialog-content>
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field>
|
||||
|
||||
@@ -4,6 +4,7 @@ import {FormBuilder, FormGroup, Validators} from '@angular/forms';
|
||||
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
||||
import {I18nService} from '../../services/i18n.service';
|
||||
import {ProfileService} from '../../services/profile.service';
|
||||
import {ConfirmDialog} from '../confirm/confirm.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-profilefields',
|
||||
@@ -55,7 +56,7 @@ export class ProfileFieldsComponent implements OnInit {
|
||||
|
||||
const dialogRef = this.dialog.open(ProfileFieldDialog, {
|
||||
data: profileField,
|
||||
minWidth : '400px'
|
||||
minWidth: '400px'
|
||||
});
|
||||
|
||||
|
||||
@@ -74,16 +75,27 @@ export class ProfileFieldsComponent implements OnInit {
|
||||
}
|
||||
|
||||
confirmDelete(profileField) {
|
||||
this.profileService.delete(profileField.name).subscribe((result: any) => {
|
||||
this.profileFields.splice(this.profileFields.indexOf(profileField), 1);
|
||||
this.profileFields = [...this.profileFields];
|
||||
const dialogRef = this.dialog.open(ConfirmDialog, {
|
||||
data: {
|
||||
'label': 'profileField.confirmDelete',
|
||||
'args': ['profileField.name.' + profileField.name]
|
||||
}
|
||||
})
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if(result) {
|
||||
this.profileService.delete(profileField.name).subscribe((result: any) => {
|
||||
this.profileFields.splice(this.profileFields.indexOf(profileField), 1);
|
||||
this.profileFields = [...this.profileFields];
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
openCreate() {
|
||||
const dialogRef = this.dialog.open(ProfileFieldDialog, {
|
||||
data: {"type": "TEXT", "visibility": "PRIVATE"},
|
||||
minWidth : '400px'
|
||||
minWidth: '400px'
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
@@ -100,7 +112,7 @@ export class ProfileFieldsComponent implements OnInit {
|
||||
openBlob(profileField) {
|
||||
this.dialog.open(ProfileFieldBlob, {
|
||||
data: profileField,
|
||||
minWidth : '400px'
|
||||
minWidth: '400px'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user