aboutsummaryrefslogtreecommitdiff
path: root/Timeline/ClientApp/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2019-03-09 01:42:38 +0800
committercrupest <crupest@outlook.com>2019-03-09 01:42:38 +0800
commitd6e7d702db4e600d2298376ba9310e985ee69079 (patch)
treeb8248d41f5bfccc82c5c110143c5504decf3e16d /Timeline/ClientApp/src
parent028af6f786ac2664d301614d57bbff053c3dc9c0 (diff)
downloadtimeline-d6e7d702db4e600d2298376ba9310e985ee69079.tar.gz
timeline-d6e7d702db4e600d2298376ba9310e985ee69079.tar.bz2
timeline-d6e7d702db4e600d2298376ba9310e985ee69079.zip
User named route in dialog.
Diffstat (limited to 'Timeline/ClientApp/src')
-rw-r--r--Timeline/ClientApp/src/app/user/entities.ts9
-rw-r--r--Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html7
-rw-r--r--Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts41
-rw-r--r--Timeline/ClientApp/src/app/user/user-info.ts4
-rw-r--r--Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts11
-rw-r--r--Timeline/ClientApp/src/app/user/user-login/user-login.component.ts20
-rw-r--r--Timeline/ClientApp/src/app/user/user-service/user.service.spec.ts13
-rw-r--r--Timeline/ClientApp/src/app/user/user-service/user.service.ts26
-rw-r--r--Timeline/ClientApp/src/app/user/user.module.ts9
9 files changed, 81 insertions, 59 deletions
diff --git a/Timeline/ClientApp/src/app/user/entities.ts b/Timeline/ClientApp/src/app/user/entities.ts
new file mode 100644
index 00000000..6d432ec6
--- /dev/null
+++ b/Timeline/ClientApp/src/app/user/entities.ts
@@ -0,0 +1,9 @@
+export interface UserCredentials {
+ username: string;
+ password: string;
+}
+
+export interface UserInfo {
+ username: string;
+ roles: string[];
+}
diff --git a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html
index 50d6ba56..58dff0e4 100644
--- a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html
+++ b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.html
@@ -1,5 +1,4 @@
-<div [ngSwitch]="state" class="container">
- <mat-progress-spinner *ngSwitchCase="'loading'" mode="indeterminate" diameter="50"></mat-progress-spinner>
- <app-user-login *ngSwitchCase="'login'" (login)="login($event)" [message]="loginMessage"></app-user-login>
- <app-user-login-success *ngSwitchCase="'success'" [userInfo]="userInfo" [displayLoginSuccessMessage]="displayLoginSuccessMessage"></app-user-login-success>
+<div class="container">
+ <mat-progress-spinner *ngIf="isLoading" mode="indeterminate" diameter="50"></mat-progress-spinner>
+ <router-outlet name="user"></router-outlet>
</div>
diff --git a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts
index 7511de16..0edde924 100644
--- a/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts
+++ b/Timeline/ClientApp/src/app/user/user-dialog/user-dialog.component.ts
@@ -1,43 +1,40 @@
-import { Component, OnInit } from '@angular/core';
-import { UserInfo } from '../user-info';
+import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { UserService } from '../user-service/user.service';
-import { LoginEvent, LoginMessage } from '../user-login/user-login.component';
+import { RouterOutlet, Router, ActivationStart } from '@angular/router';
@Component({
selector: 'app-user-dialog',
templateUrl: './user-dialog.component.html',
styleUrls: ['./user-dialog.component.css']
})
-export class UserDialogComponent implements OnInit {
+export class UserDialogComponent implements OnInit, OnDestroy {
- constructor(private userService: UserService) { }
+ constructor(private userService: UserService, private router: Router) { }
- state: 'loading' | 'login' | 'success' = 'loading';
+ @ViewChild(RouterOutlet) outlet: RouterOutlet;
- loginMessage: LoginMessage;
-
- displayLoginSuccessMessage = false;
- userInfo: UserInfo;
+ isLoading = true;
ngOnInit() {
+ // this is a workaround for a bug. see https://github.com/angular/angular/issues/20694
+ this.router.events.subscribe(e => {
+ if (e instanceof ActivationStart && e.snapshot.outlet === 'user') {
+ this.outlet.deactivate();
+ }
+ });
+
+
this.userService.validateUserLoginState().subscribe(result => {
+ this.isLoading = false;
if (result.state === 'success') {
- this.userInfo = result.userInfo;
- this.state = 'success';
+ this.userService.userRouteNavigate(['success', { reason: 'already' }]);
} else {
- this.loginMessage = result.state;
- this.state = 'login';
+ this.userService.userRouteNavigate(['login', { reason: result.state }]);
}
});
}
- login(event: LoginEvent) {
- this.userService.tryLogin(event.username, event.password).subscribe(result => {
- this.userInfo = result;
- this.displayLoginSuccessMessage = true;
- this.state = 'success';
- }, (error: Error) => {
- this.loginMessage = error.message;
- });
+ ngOnDestroy() {
+ this.userService.userRouteNavigate(null);
}
}
diff --git a/Timeline/ClientApp/src/app/user/user-info.ts b/Timeline/ClientApp/src/app/user/user-info.ts
deleted file mode 100644
index 490b00ba..00000000
--- a/Timeline/ClientApp/src/app/user/user-info.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface UserInfo {
- username: string;
- roles: string[];
-}
diff --git a/Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts b/Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts
index 99de5970..d141b3b6 100644
--- a/Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts
+++ b/Timeline/ClientApp/src/app/user/user-login-success/user-login-success.component.ts
@@ -1,5 +1,7 @@
import { Component, OnInit, Input } from '@angular/core';
-import { UserInfo } from '../user-info';
+import { UserInfo } from '../entities';
+import { UserService } from '../user-service/user.service';
+import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-user-login-success',
@@ -8,15 +10,14 @@ import { UserInfo } from '../user-info';
})
export class UserLoginSuccessComponent implements OnInit {
- @Input()
displayLoginSuccessMessage = false;
- @Input()
userInfo: UserInfo;
- constructor() { }
+ constructor(private route: ActivatedRoute, private userService: UserService) { }
ngOnInit() {
+ this.userInfo = this.userService.userInfo;
+ this.displayLoginSuccessMessage = this.route.snapshot.paramMap.get('reason') === 'login';
}
-
}
diff --git a/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts b/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts
index da642cb8..971d57ce 100644
--- a/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts
+++ b/Timeline/ClientApp/src/app/user/user-login/user-login.component.ts
@@ -1,5 +1,7 @@
-import { Component, Output, OnInit, EventEmitter, Input } from '@angular/core';
+import { Component, Output, OnInit, EventEmitter } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
+import { UserService } from '../user-service/user.service';
+import { ActivatedRoute } from '@angular/router';
export type LoginMessage = 'nologin' | 'invalidlogin' | string;
@@ -13,20 +15,24 @@ export class LoginEvent {
templateUrl: './user-login.component.html',
styleUrls: ['./user-login.component.css']
})
-export class UserLoginComponent {
+export class UserLoginComponent implements OnInit {
- @Input()
- message: LoginMessage;
+ constructor(private route: ActivatedRoute, private userService: UserService) { }
- @Output()
- login = new EventEmitter<LoginEvent>();
+ message: string;
form = new FormGroup({
username: new FormControl(''),
password: new FormControl('')
});
+ ngOnInit() {
+ this.message = this.route.snapshot.paramMap.get('reason');
+ }
+
onLoginButtonClick() {
- this.login.emit(this.form.value);
+ this.userService.tryLogin(this.form.value).subscribe(_ => {
+ this.userService.userRouteNavigate(['success', { reason: 'login' }]);
+ }, (error: Error) => this.message = error.message);
}
}
diff --git a/Timeline/ClientApp/src/app/user/user-service/user.service.spec.ts b/Timeline/ClientApp/src/app/user/user-service/user.service.spec.ts
index 0095f031..9effe000 100644
--- a/Timeline/ClientApp/src/app/user/user-service/user.service.spec.ts
+++ b/Timeline/ClientApp/src/app/user/user-service/user.service.spec.ts
@@ -2,15 +2,20 @@ import { TestBed } from '@angular/core/testing';
import { HttpRequest } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
-import { UserInfo } from '../user-info';
+import { UserInfo, UserCredentials } from '../entities';
import {
- UserService, UserCredentials, CreateTokenResult,
+ UserService, CreateTokenResult,
UserLoginState, TokenValidationRequest, TokenValidationResult
} from './user.service';
describe('UserService', () => {
const tokenCreateUrl = '/api/User/CreateToken';
+ const mockUserCredentials: UserCredentials = {
+ username: 'user',
+ password: 'user'
+ };
+
beforeEach(() => TestBed.configureTestingModule({
imports: [HttpClientTestingModule]
}));
@@ -35,7 +40,7 @@ describe('UserService', () => {
roles: ['user', 'other']
};
- service.tryLogin('user', 'user').subscribe(result => {
+ service.tryLogin(mockUserCredentials).subscribe(result => {
expect(result).toEqual(mockUserInfo);
});
@@ -71,7 +76,7 @@ describe('UserService', () => {
service = TestBed.get(UserService);
httpController = TestBed.get(HttpTestingController);
- service.tryLogin('user', 'user').subscribe(); // subscribe to activate login
+ service.tryLogin(mockUserCredentials).subscribe(); // subscribe to activate login
httpController.expectOne(tokenCreateUrl).flush(<CreateTokenResult>{
token: mockToken,
diff --git a/Timeline/ClientApp/src/app/user/user-service/user.service.ts b/Timeline/ClientApp/src/app/user/user-service/user.service.ts
index 009e5292..e535537d 100644
--- a/Timeline/ClientApp/src/app/user/user-service/user.service.ts
+++ b/Timeline/ClientApp/src/app/user/user-service/user.service.ts
@@ -3,12 +3,8 @@ import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { map, catchError, retry } from 'rxjs/operators';
-import { UserInfo } from '../user-info';
-
-export interface UserCredentials {
- username: string;
- password: string;
-}
+import { UserCredentials, UserInfo } from '../entities';
+import { Router } from '@angular/router';
export interface CreateTokenResult {
token: string;
@@ -53,9 +49,17 @@ export class BadCredentialsException extends Error {
export class UserService {
private token: string;
- private userInfo: UserInfo;
+ userInfo: UserInfo;
- constructor(private httpClient: HttpClient) { }
+ constructor(private httpClient: HttpClient, private router: Router) { }
+
+ userRouteNavigate(commands: any[]) {
+ this.router.navigate([{
+ outlets: {
+ user: commands
+ }
+ }]);
+ }
validateUserLoginState(): Observable<UserLoginState> {
if (this.token === undefined || this.token === null) {
@@ -86,14 +90,12 @@ export class UserService {
);
}
- tryLogin(username: string, password: string): Observable<UserInfo> {
+ tryLogin(credentials: UserCredentials): Observable<UserInfo> {
if (this.token) {
return throwError(new AlreadyLoginException());
}
- return this.httpClient.post<CreateTokenResult>('/api/User/CreateToken', <UserCredentials>{
- username, password
- }).pipe(
+ return this.httpClient.post<CreateTokenResult>('/api/User/CreateToken', credentials).pipe(
catchError((error: HttpErrorResponse) => {
if (error.error instanceof ErrorEvent) {
console.error('An error occurred when login: ' + error.error.message);
diff --git a/Timeline/ClientApp/src/app/user/user.module.ts b/Timeline/ClientApp/src/app/user/user.module.ts
index 67de90a2..1e70d33d 100644
--- a/Timeline/ClientApp/src/app/user/user.module.ts
+++ b/Timeline/ClientApp/src/app/user/user.module.ts
@@ -11,14 +11,21 @@ import { UserDialogComponent } from './user-dialog/user-dialog.component';
import { UserLoginComponent } from './user-login/user-login.component';
import { UserLoginSuccessComponent } from './user-login-success/user-login-success.component';
import { UtilityModule } from '../utility/utility.module';
+import { RouterModule } from '@angular/router';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [UserDialogComponent, UserLoginComponent, UserLoginSuccessComponent],
imports: [
- CommonModule, HttpClientModule, ReactiveFormsModule,
+ RouterModule.forChild([
+ { path: 'login', component: UserLoginComponent, outlet: 'user' },
+ { path: 'success', component: UserLoginSuccessComponent, outlet: 'user' }
+ ]),
+ CommonModule, HttpClientModule, ReactiveFormsModule, BrowserAnimationsModule,
MatFormFieldModule, MatProgressSpinnerModule, MatDialogModule, MatInputModule, MatButtonModule,
UtilityModule
],
+ exports: [RouterModule],
entryComponents: [UserDialogComponent]
})
export class UserModule { }