Start work on login

This commit is contained in:
Simon Hanna 2018-09-10 14:00:39 +02:00
parent 7473365157
commit 994367c147
10 changed files with 133 additions and 20 deletions

View File

@ -18,6 +18,8 @@
<mat-toolbar style="background-color: #64aef3;">
<button mat-icon-button (click)="menu.toggle()"><mat-icon>menu</mat-icon></button>
<span>OpenLP Remote</span>
<span class="filler"></span>
<button *ngIf="showLogin" mat-button (click)="login()">Login</button>
</mat-toolbar>
</header>
<main class="content">

View File

@ -11,6 +11,10 @@ mat-sidenav {
min-height: 100vh;
}
.filler {
flex-grow: 1;
}
.content {
flex: 1;
}

View File

@ -1,20 +1,40 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { State } from './responses';
import { OpenLPService } from './openlp.service';
import { MatSlideToggleChange } from '@angular/material';
import { MatSlideToggleChange, MatDialog } from '@angular/material';
import { LoginComponent } from './components/login/login.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
export class AppComponent implements OnInit {
fastSwitching: boolean = false;
state: State = new State();
showLogin: boolean = false;
constructor(private openlpService: OpenLPService) {
constructor(private openlpService: OpenLPService, private dialog: MatDialog) {
openlpService.stateChanged$.subscribe(item => this.state = item);
}
ngOnInit(): void {
this.openlpService.retrieveSystemInformation().subscribe(res => this.showLogin = res.login_required);
}
login() {
const dialogRef = this.dialog.open(LoginComponent, {
width: '250px'
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.showLogin = false;
this.openlpService.setAuthToken(result.token);
}
})
}
nextItem() {
this.openlpService.nextItem().subscribe();

View File

@ -11,7 +11,7 @@ import {MatGridListModule} from '@angular/material/grid-list';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatSelectModule} from '@angular/material/select';
import {MatButtonModule} from '@angular/material/button';
import {MatInputModule} from '@angular/material';
import {MatInputModule, MatCardModule, MatDialogModule, MatSnackBarModule} from '@angular/material';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
@ -29,6 +29,7 @@ import { ChordViewComponent } from './components/chord-view/chord-view.component
import { StageViewComponent } from './components/stage-view/stage-view.component';
import { MainViewComponent } from './components/main-view/main-view.component';
import { ChordProPipe } from './components/chord-view/chordpro.pipe';
import { LoginComponent } from './components/login/login.component';
@NgModule({
@ -41,7 +42,8 @@ import { ChordProPipe } from './components/chord-view/chordpro.pipe';
ChordViewComponent,
StageViewComponent,
MainViewComponent,
ChordProPipe
ChordProPipe,
LoginComponent
],
imports: [
BrowserModule,
@ -59,11 +61,17 @@ import { ChordProPipe } from './components/chord-view/chordpro.pipe';
MatButtonModule,
MatInputModule,
MatTooltipModule,
MatSlideToggleModule
MatSlideToggleModule,
MatCardModule,
MatDialogModule,
MatSnackBarModule
],
providers: [
OpenLPService
],
entryComponents: [
LoginComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -0,0 +1,15 @@
<h1 mat-dialog-title>Login</h1>
<form #loginForm="ngForm">
<div mat-dialog-content>
<mat-form-field>
<input matInput placeholder="Username" [(ngModel)]="username" name="username" required>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="password" type="password" [(ngModel)]="password" name="password" required>
</mat-form-field>
</div>
<div mat-dialog-actions>
<button mat-raised-button id="loginButton" color="primary" [disabled]="!loginForm.form.valid" (click)="performLogin()">Login</button>
</div>
</form>

View File

@ -0,0 +1,3 @@
mat-form-field {
width: 100%;
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LoginComponent } from './login.component';
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,29 @@
import { Component, OnInit } from '@angular/core';
import { Credentials } from '../../responses';
import { MatDialogRef, MatSnackBar } from '@angular/material';
import { OpenLPService } from '../../openlp.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
username: string;
password: string;
constructor(private dialogRef: MatDialogRef<LoginComponent>, private openlpService: OpenLPService,
private snackBar: MatSnackBar) { }
ngOnInit() {
}
performLogin() {
this.openlpService.login({username: this.username, password: this.password}).subscribe(
result => {
this.snackBar.open('Successfully logged in', '', {duration: 2000})
this.dialogRef.close(result);
},
err => this.snackBar.open('Login failed', '', {duration: 2000})
)
}
}

View File

@ -5,7 +5,7 @@ import { URLSearchParams, Http } from '@angular/http';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { PluginDescription, State, Slide, ServiceItem, MainView, SystemInformation } from './responses';
import { PluginDescription, State, Slide, ServiceItem, MainView, SystemInformation, Credentials, AuthToken } from './responses';
import { environment } from '../environments/environment';
@ -55,19 +55,12 @@ export class OpenLPService {
});
}
private retrieveSystemInformation(): Observable<SystemInformation> {
return this.http.get<SystemInformation>(`${this.apiURL}/core/system`);
setAuthToken(token: string): void {
httpOptions.headers = httpOptions.headers.set('Authorization', token);
}
getSystemInformation(): SystemInformation {
let information = sessionStorage.getItem('system_information');
if (information) {
return JSON.parse(information);
}
this.retrieveSystemInformation().subscribe(information => {
sessionStorage.setItem('system_information', JSON.stringify(information));
return information;
});
retrieveSystemInformation(): Observable<SystemInformation> {
return this.http.get<SystemInformation>(`${this.apiURL}/core/system`, httpOptions);
}
getMainImage(): Observable<MainView> {
@ -83,7 +76,7 @@ export class OpenLPService {
}
getSearchablePlugins(): Observable<PluginDescription[]> {
return this.http.get<PluginDescription[]>(`${this.apiURL}/core/plugins`);
return this.http.get<PluginDescription[]>(`${this.apiURL}/core/plugins`, httpOptions);
}
setServiceItem(id:number): Observable<any> {
@ -142,4 +135,8 @@ export class OpenLPService {
addItemToService(plugin, id): Observable<any> {
return this.http.post(`${this.apiURL}/plugins/${plugin}/add`, {'id': id}, httpOptions);
}
login(credentials: Credentials): Observable<AuthToken> {
return this.http.post<AuthToken>(`${this.apiURL}/core/login`, credentials, httpOptions);
}
}

View File

@ -41,4 +41,14 @@ export interface MainView {
export interface SystemInformation {
websocket_port: number;
login_required: boolean;
}
export interface Credentials {
username: string;
password: string;
}
export interface AuthToken {
token: string;
}