Add progress bars for login and budget creation; fix budget creation

Signed-off-by: William Brawner <me@wbrawner.com>
This commit is contained in:
William Brawner 2020-02-25 03:40:03 +00:00
parent 3ab5413c43
commit 6aa76d6743
8 changed files with 46 additions and 17 deletions

View file

@ -1,7 +1,8 @@
<div [hidden]="budget"> <mat-progress-spinner *ngIf="isLoading" mode="indeterminate" diameter="50"></mat-progress-spinner>
<div *ngIf="!isLoading && !budget">
<p>Select a budget from the list to view details about it or edit it.</p> <p>Select a budget from the list to view details about it or edit it.</p>
</div> </div>
<div [hidden]="!budget" class="form budget-form"> <div *ngIf="!isLoading && budget" class="form budget-form">
<mat-form-field> <mat-form-field>
<input matInput [(ngModel)]="budget.name" placeholder="Name" required> <input matInput [(ngModel)]="budget.name" placeholder="Name" required>
</mat-form-field> </mat-form-field>

View file

@ -1,7 +1,7 @@
import { Component, OnInit, Input, Inject, OnDestroy } from '@angular/core'; import { Component, OnInit, Input, Inject, OnDestroy } from '@angular/core';
import { Budget } from '../budget'; import { Budget } from '../budget';
import { AppComponent } from 'src/app/app.component'; import { AppComponent } from 'src/app/app.component';
import { User } from 'src/app/users/user'; import { User, UserPermission, Permission } from 'src/app/users/user';
import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service'; import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
@Component({ @Component({
@ -12,8 +12,9 @@ import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
export class AddEditBudgetComponent { export class AddEditBudgetComponent {
@Input() title: string; @Input() title: string;
@Input() budget: Budget; @Input() budget: Budget;
public userIds: number[]; public users: UserPermission[];
public searchedUsers: User[] = []; public searchedUsers: User[] = [];
public isLoading = false;
constructor( constructor(
private app: AppComponent, private app: AppComponent,
@ -21,11 +22,12 @@ export class AddEditBudgetComponent {
) { ) {
this.app.title = this.title; this.app.title = this.title;
this.app.backEnabled = true; this.app.backEnabled = true;
this.userIds = [this.app.user.id]; this.users = [new UserPermission(this.app.user.id, Permission.OWNER)];
} }
save(): void { save(): void {
let observable; let observable;
this.isLoading = true;
if (this.budget.id) { if (this.budget.id) {
// This is an existing transaction, update it // This is an existing transaction, update it
observable = this.twigsService.updateBudget(this.budget.id, this.budget); observable = this.twigsService.updateBudget(this.budget.id, this.budget);
@ -34,7 +36,7 @@ export class AddEditBudgetComponent {
observable = this.twigsService.createBudget( observable = this.twigsService.createBudget(
this.budget.name, this.budget.name,
this.budget.description, this.budget.description,
this.userIds this.users
); );
} }
// TODO: Check if it was actually successful or not // TODO: Check if it was actually successful or not
@ -44,6 +46,7 @@ export class AddEditBudgetComponent {
} }
delete(): void { delete(): void {
this.isLoading = true;
this.twigsService.deleteBudget(this.budget.id); this.twigsService.deleteBudget(this.budget.id);
this.app.goBack(); this.app.goBack();
} }

View file

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http'; import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { Observable, Subscriber } from 'rxjs'; import { Observable, Subscriber } from 'rxjs';
import { User } from '../users/user'; import { User, UserPermission, Permission } from '../users/user';
import { TwigsService } from './twigs.service'; import { TwigsService } from './twigs.service';
import { Budget } from '../budgets/budget'; import { Budget } from '../budgets/budget';
import { Category } from '../categories/category'; import { Category } from '../categories/category';
@ -43,7 +43,7 @@ export class TwigsHttpService implements TwigsService {
} }
logout(): Observable<void> { logout(): Observable<void> {
return this.http.post<void>(this.apiUrl + '/logout', this.options); return this.http.post<void>(this.apiUrl + '/login?logout', this.options);
} }
// Budgets // Budgets
@ -58,12 +58,17 @@ export class TwigsHttpService implements TwigsService {
createBudget( createBudget(
name: string, name: string,
description: string, description: string,
userIds: number[], users: UserPermission[],
): Observable<Budget> { ): Observable<Budget> {
const params = { const params = {
'name': name, 'name': name,
'description': description, 'description': description,
'userIds': userIds 'users': users.map(user => {
return {
user: user.user,
permission: Permission[user.permission]
};
})
}; };
return this.http.post<Budget>(this.apiUrl + '/budgets/new', params, this.options); return this.http.post<Budget>(this.apiUrl + '/budgets/new', params, this.options);
} }

View file

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http'; import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { Observable, Subscriber } from 'rxjs'; import { Observable, Subscriber } from 'rxjs';
import { User } from '../users/user'; import { User, UserPermission } from '../users/user';
import { TwigsService } from './twigs.service'; import { TwigsService } from './twigs.service';
import { Budget } from '../budgets/budget'; import { Budget } from '../budgets/budget';
import { Category } from '../categories/category'; import { Category } from '../categories/category';
@ -82,14 +82,14 @@ export class TwigsLocalService implements TwigsService {
createBudget( createBudget(
name: string, name: string,
description: string, description: string,
userIds: number[], users: UserPermission[],
): Observable<Budget> { ): Observable<Budget> {
return Observable.create(subscriber => { return Observable.create(subscriber => {
const budget = new Budget(); const budget = new Budget();
budget.name = name; budget.name = name;
budget.description = description; budget.description = description;
budget.users = this.users.filter(user => { budget.users = this.users.filter(user => {
return userIds.indexOf(user.id) > -1; return users.map(userPerm => userPerm.user).indexOf(user.id) > -1;
}); });
budget.id = this.budgets.length + 1; budget.id = this.budgets.length + 1;
this.budgets.push(budget); this.budgets.push(budget);

View file

@ -1,6 +1,6 @@
import { InjectionToken } from '@angular/core'; import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { User } from '../users/user'; import { User, UserPermission } from '../users/user';
import { Budget } from '../budgets/budget'; import { Budget } from '../budgets/budget';
import { Category } from '../categories/category'; import { Category } from '../categories/category';
import { Transaction } from '../transactions/transaction'; import { Transaction } from '../transactions/transaction';
@ -17,7 +17,7 @@ export interface TwigsService {
createBudget( createBudget(
name: string, name: string,
description: string, description: string,
userIds: number[], users: UserPermission[],
): Observable<Budget>; ): Observable<Budget>;
updateBudget(id: number, changes: object): Observable<Budget>; updateBudget(id: number, changes: object): Observable<Budget>;
deleteBudget(id: number): Observable<void>; deleteBudget(id: number): Observable<void>;

View file

@ -1,9 +1,10 @@
<div class="form login-form"> <mat-progress-spinner *ngIf="isLoading" mode="indeterminate" diameter="50"></mat-progress-spinner>
<div *ngIf="!isLoading" class="form login-form">
<mat-form-field> <mat-form-field>
<input matInput placeholder="Email" [(ngModel)]="email" /> <input matInput placeholder="Email" [(ngModel)]="email" />
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<input matInput type="password" placeholder="Password" [(ngModel)]="password" (keyup.enter)="doAction()"/> <input matInput type="password" placeholder="Password" [(ngModel)]="password" (keyup.enter)="login()"/>
</mat-form-field> </mat-form-field>
<button mat-raised-button color="accent" (click)="login()">Login</button> <button mat-raised-button color="accent" (click)="login()">Login</button>
</div> </div>

View file

@ -11,6 +11,7 @@ import { Router } from '@angular/router';
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
public isLoading = false;
public email: string; public email: string;
public password: string; public password: string;
@ -26,6 +27,7 @@ export class LoginComponent implements OnInit {
} }
login(): void { login(): void {
this.isLoading = true;
this.twigsService.login(this.email, this.password) this.twigsService.login(this.email, this.password)
.subscribe(user => { .subscribe(user => {
this.app.user = user; this.app.user = user;
@ -34,6 +36,7 @@ export class LoginComponent implements OnInit {
error => { error => {
console.error(error) console.error(error)
alert("Login failed. Please verify you have the correct credentials"); alert("Login failed. Please verify you have the correct credentials");
this.isLoading = false;
}) })
} }
} }

View file

@ -9,3 +9,19 @@ export class User {
this.email = email; this.email = email;
} }
} }
export class UserPermission {
user: number;
permission: Permission;
constructor(user: number, permission: Permission) {
this.user = user;
this.permission = permission;
}
}
export enum Permission {
READ,
WRITE,
OWNER
}