Use strings instead of numbers for id and generate client-side
This commit is contained in:
parent
06850c8b8e
commit
92f93861e9
29 changed files with 172 additions and 145 deletions
|
@ -10,5 +10,5 @@
|
|||
<textarea matInput [(ngModel)]="budget.description" placeholder="Description"></textarea>
|
||||
</mat-form-field>
|
||||
<button mat-raised-button color="accent" (click)="save()">Save</button>
|
||||
<button class="button-delete" mat-raised-button color="warn" *ngIf="budget.id" (click)="delete()">Delete</button>
|
||||
<button class="button-delete" mat-raised-button color="warn" *ngIf="!create" (click)="delete()">Delete</button>
|
||||
</div>
|
||||
|
|
|
@ -12,6 +12,7 @@ import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
|
|||
export class AddEditBudgetComponent {
|
||||
@Input() title: string;
|
||||
@Input() budget: Budget;
|
||||
@Input() create: boolean;
|
||||
public users: UserPermission[];
|
||||
public searchedUsers: User[] = [];
|
||||
public isLoading = false;
|
||||
|
@ -28,16 +29,17 @@ export class AddEditBudgetComponent {
|
|||
save(): void {
|
||||
let observable;
|
||||
this.isLoading = true;
|
||||
if (this.budget.id) {
|
||||
// This is an existing budget, update it
|
||||
observable = this.twigsService.updateBudget(this.budget.id, this.budget);
|
||||
} else {
|
||||
if (this.create) {
|
||||
// This is a new budget, save it
|
||||
observable = this.twigsService.createBudget(
|
||||
this.budget.id,
|
||||
this.budget.name,
|
||||
this.budget.description,
|
||||
this.users
|
||||
);
|
||||
} else {
|
||||
// This is an existing budget, update it
|
||||
observable = this.twigsService.updateBudget(this.budget.id, this.budget);
|
||||
}
|
||||
// TODO: Check if it was actually successful or not
|
||||
observable.subscribe(val => {
|
||||
|
|
|
@ -21,7 +21,7 @@ export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
|
|||
public transactions: Transaction[];
|
||||
public expenses: Category[] = [];
|
||||
public income: Category[] = [];
|
||||
categoryBalances: Map<number, number>;
|
||||
categoryBalances: Map<string, number>;
|
||||
expectedIncome = 0;
|
||||
actualIncome = 0;
|
||||
expectedExpenses = 0;
|
||||
|
@ -51,7 +51,7 @@ export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
|
|||
}
|
||||
|
||||
getBudget() {
|
||||
const id = Number.parseInt(this.route.snapshot.paramMap.get('id'));
|
||||
const id = this.route.snapshot.paramMap.get('id');
|
||||
this.twigsService.getBudget(id)
|
||||
.subscribe(budget => {
|
||||
this.app.setTitle(budget.name)
|
||||
|
@ -108,7 +108,7 @@ export class BudgetDetailsComponent implements OnInit, OnDestroy, Actionable {
|
|||
|
||||
getCategories(): void {
|
||||
this.twigsService.getCategories(this.budget.id).subscribe(categories => {
|
||||
const categoryBalances = new Map<number, number>();
|
||||
const categoryBalances = new Map<string, number>();
|
||||
let categoryBalancesCount = 0;
|
||||
console.log(categories);
|
||||
for (const category of categories) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { UserPermission } from '../users/user';
|
||||
import { uuidv4 } from '../shared/utils';
|
||||
|
||||
export class Budget {
|
||||
id: number;
|
||||
id: string = uuidv4();
|
||||
name: string;
|
||||
description: string;
|
||||
users: UserPermission[];
|
||||
|
|
|
@ -1 +1 @@
|
|||
<app-add-edit-budget [title]="'Edit Budget'" [budget]="budget"></app-add-edit-budget>
|
||||
<app-add-edit-budget [title]="'Edit Budget'" [budget]="budget" [create]="false"></app-add-edit-budget>
|
||||
|
|
|
@ -18,7 +18,7 @@ export class EditBudgetComponent implements OnInit {
|
|||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
const id = Number.parseInt(this.route.snapshot.paramMap.get('id'));
|
||||
const id = this.route.snapshot.paramMap.get('id');
|
||||
this.twigsService.getBudget(id)
|
||||
.subscribe(budget => {
|
||||
this.budget = budget;
|
||||
|
|
|
@ -1 +1 @@
|
|||
<app-add-edit-budget [title]="'Add Budget'" [budget]="budget"></app-add-edit-budget>
|
||||
<app-add-edit-budget [title]="'Add Budget'" [budget]="budget" [create]="true"></app-add-edit-budget>
|
|
@ -14,9 +14,9 @@ import { TWIGS_SERVICE, TwigsService } from '../shared/twigs.service';
|
|||
})
|
||||
export class CategoriesComponent implements OnInit {
|
||||
|
||||
budgetId: number;
|
||||
budgetId: string;
|
||||
public categories: Category[];
|
||||
public categoryBalances: Map<number, number>;
|
||||
public categoryBalances: Map<string, number>;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
|
@ -25,7 +25,7 @@ export class CategoriesComponent implements OnInit {
|
|||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.budgetId = Number.parseInt(this.route.snapshot.paramMap.get('budgetId'));
|
||||
this.budgetId = this.route.snapshot.paramMap.get('budgetId');
|
||||
this.app.setTitle('Categories')
|
||||
this.app.setBackEnabled(true);
|
||||
this.getCategories();
|
||||
|
|
|
@ -13,7 +13,7 @@ import { Actionable } from '../../shared/actionable';
|
|||
})
|
||||
export class CategoryDetailsComponent implements OnInit, OnDestroy, Actionable {
|
||||
|
||||
budgetId: number;
|
||||
budgetId: string;
|
||||
category: Category;
|
||||
public transactions: Transaction[];
|
||||
|
||||
|
@ -43,7 +43,7 @@ export class CategoryDetailsComponent implements OnInit, OnDestroy, Actionable {
|
|||
}
|
||||
|
||||
getCategory(): void {
|
||||
const id = Number.parseInt(this.route.snapshot.paramMap.get('id'));
|
||||
const id = this.route.snapshot.paramMap.get('id');
|
||||
this.twigsService.getCategory(id)
|
||||
.subscribe(category => {
|
||||
category.amount /= 100;
|
||||
|
|
|
@ -22,5 +22,5 @@
|
|||
</mat-form-field>
|
||||
-->
|
||||
<button mat-raised-button color="accent" (click)="save()">Save</button>
|
||||
<button class="button-delete" mat-raised-button color="warn" *ngIf="currentCategory.id" (click)="delete()">Delete</button>
|
||||
<button class="button-delete" mat-raised-button color="warn" *ngIf="!create" (click)="delete()">Delete</button>
|
||||
</div>
|
|
@ -10,9 +10,10 @@ import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
|
|||
})
|
||||
export class CategoryFormComponent implements OnInit {
|
||||
|
||||
@Input() budgetId: number;
|
||||
@Input() budgetId: string;
|
||||
@Input() title: string;
|
||||
@Input() currentCategory: Category;
|
||||
@Input() create: boolean;
|
||||
|
||||
constructor(
|
||||
private app: AppComponent,
|
||||
|
@ -26,10 +27,19 @@ export class CategoryFormComponent implements OnInit {
|
|||
|
||||
save(): void {
|
||||
let observable;
|
||||
if (this.currentCategory.id) {
|
||||
if (this.create) {
|
||||
// This is a new category, save it
|
||||
observable = this.twigsService.createCategory(
|
||||
this.currentCategory.id,
|
||||
this.budgetId,
|
||||
this.currentCategory.title,
|
||||
this.currentCategory.description,
|
||||
this.currentCategory.amount * 100,
|
||||
this.currentCategory.expense
|
||||
);
|
||||
} else {
|
||||
// This is an existing category, update it
|
||||
observable = this.twigsService.updateCategory(
|
||||
this.budgetId,
|
||||
this.currentCategory.id,
|
||||
{
|
||||
name: this.currentCategory.title,
|
||||
|
@ -39,15 +49,6 @@ export class CategoryFormComponent implements OnInit {
|
|||
archived: this.currentCategory.archived
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// This is a new category, save it
|
||||
observable = this.twigsService.createCategory(
|
||||
this.budgetId,
|
||||
this.currentCategory.title,
|
||||
this.currentCategory.description,
|
||||
this.currentCategory.amount * 100,
|
||||
this.currentCategory.expense
|
||||
);
|
||||
}
|
||||
observable.subscribe(val => {
|
||||
this.app.goBack();
|
||||
|
@ -55,7 +56,7 @@ export class CategoryFormComponent implements OnInit {
|
|||
}
|
||||
|
||||
delete(): void {
|
||||
this.twigsService.deleteCategory(this.budgetId, this.currentCategory.id).subscribe(() => {
|
||||
this.twigsService.deleteCategory(this.currentCategory.id).subscribe(() => {
|
||||
this.app.goBack();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ export class CategoryListComponent implements OnInit {
|
|||
|
||||
@Input() budgetId: string;
|
||||
@Input() categories: Category[];
|
||||
@Input() categoryBalances: Map<number, number>;
|
||||
@Input() categoryBalances: Map<string, number>;
|
||||
|
||||
constructor() { }
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { uuidv4 } from '../shared/utils';
|
||||
|
||||
export class Category {
|
||||
id: number;
|
||||
id: string = uuidv4();
|
||||
title: string;
|
||||
description: string;
|
||||
amount: number;
|
||||
expense: boolean;
|
||||
archived: boolean;
|
||||
budgetId: number;
|
||||
budgetId: string;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
<app-category-form [title]="'Edit Category'" [budgetId]="budgetId" [currentCategory]="category"></app-category-form>
|
||||
<app-category-form [title]="'Edit Category'" [budgetId]="budgetId" [currentCategory]="category" [create]="false"></app-category-form>
|
||||
|
|
|
@ -11,7 +11,7 @@ import { TWIGS_SERVICE, TwigsService } from '../../shared/twigs.service';
|
|||
})
|
||||
export class EditCategoryComponent implements OnInit {
|
||||
|
||||
budgetId: number;
|
||||
budgetId: string;
|
||||
category: Category;
|
||||
|
||||
constructor(
|
||||
|
@ -26,7 +26,7 @@ export class EditCategoryComponent implements OnInit {
|
|||
}
|
||||
|
||||
getCategory(): void {
|
||||
const id = Number.parseInt(this.route.snapshot.paramMap.get('id'));
|
||||
const id = this.route.snapshot.paramMap.get('id');
|
||||
this.twigsService.getCategory(id)
|
||||
.subscribe(category => {
|
||||
category.amount /= 100;
|
||||
|
|
|
@ -1 +1 @@
|
|||
<app-category-form [title]="'Add Category'" [budgetId]="budgetId" [currentCategory]="category"></app-category-form>
|
||||
<app-category-form [title]="'Add Category'" [budgetId]="budgetId" [currentCategory]="category" [create]="true"></app-category-form>
|
||||
|
|
|
@ -67,7 +67,7 @@ export class TwigsHttpService implements TwigsService {
|
|||
return this.budgets;
|
||||
}
|
||||
|
||||
getBudget(id: number): Observable<Budget> {
|
||||
getBudget(id: string): Observable<Budget> {
|
||||
return new Observable(emitter => {
|
||||
var cachedBudget: Budget
|
||||
if (this.budgets.value) {
|
||||
|
@ -96,11 +96,13 @@ export class TwigsHttpService implements TwigsService {
|
|||
}
|
||||
|
||||
createBudget(
|
||||
id: string,
|
||||
name: string,
|
||||
description: string,
|
||||
users: UserPermission[],
|
||||
): Observable<Budget> {
|
||||
const params = {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'users': users.map(userPermission => {
|
||||
|
@ -120,7 +122,7 @@ export class TwigsHttpService implements TwigsService {
|
|||
}))
|
||||
}
|
||||
|
||||
updateBudget(id: number, changes: object): Observable<Budget> {
|
||||
updateBudget(id: string, changes: object): Observable<Budget> {
|
||||
let budget = changes as Budget;
|
||||
const params = {
|
||||
'name': budget.name,
|
||||
|
@ -146,7 +148,7 @@ export class TwigsHttpService implements TwigsService {
|
|||
}));
|
||||
}
|
||||
|
||||
deleteBudget(id: number): Observable<void> {
|
||||
deleteBudget(id: String): Observable<void> {
|
||||
return this.http.delete<void>(`${this.apiUrl}/budgets/${id}`, this.options)
|
||||
.pipe(map(() => {
|
||||
var updatedBudgets: Budget[] = JSON.parse(JSON.stringify(this.budgets.value));
|
||||
|
@ -161,7 +163,7 @@ export class TwigsHttpService implements TwigsService {
|
|||
}
|
||||
|
||||
// Categories
|
||||
getCategories(budgetId: number, count?: number): Observable<Category[]> {
|
||||
getCategories(budgetId: string, count?: number): Observable<Category[]> {
|
||||
const params = {
|
||||
params: new HttpParams()
|
||||
.set('budgetIds', `${budgetId}`)
|
||||
|
@ -169,17 +171,18 @@ export class TwigsHttpService implements TwigsService {
|
|||
return this.http.get<Category[]>(`${this.apiUrl}/categories`, Object.assign(params, this.options));
|
||||
}
|
||||
|
||||
getCategory(id: number): Observable<Category> {
|
||||
getCategory(id: string): Observable<Category> {
|
||||
return this.http.get<Category>(`${this.apiUrl}/categories/${id}`, this.options);
|
||||
}
|
||||
|
||||
getCategoryBalance(id: number): Observable<number> {
|
||||
getCategoryBalance(id: string): Observable<number> {
|
||||
return this.http.get<any>(`${this.apiUrl}/categories/${id}/balance`, this.options)
|
||||
.pipe(map(obj => obj.balance));
|
||||
}
|
||||
|
||||
createCategory(budgetId: number, name: string, description: string, amount: number, isExpense: boolean): Observable<Category> {
|
||||
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Observable<Category> {
|
||||
const params = {
|
||||
'id': id,
|
||||
'title': name,
|
||||
'description': description,
|
||||
'amount': amount,
|
||||
|
@ -189,18 +192,18 @@ export class TwigsHttpService implements TwigsService {
|
|||
return this.http.post<Category>(this.apiUrl + '/categories', params, this.options);
|
||||
}
|
||||
|
||||
updateCategory(budgetId: number, id: number, changes: object): Observable<Category> {
|
||||
updateCategory(id: string, changes: object): Observable<Category> {
|
||||
return this.http.put<Category>(`${this.apiUrl}/categories/${id}`, changes, this.options);
|
||||
}
|
||||
|
||||
deleteCategory(budgetId: number, id: number): Observable<void> {
|
||||
deleteCategory(id: string): Observable<void> {
|
||||
return this.http.delete<void>(`${this.apiUrl}/categories/${id}`, this.options);
|
||||
}
|
||||
|
||||
// Transactions
|
||||
getTransactions(
|
||||
budgetId?: number,
|
||||
categoryId?: number,
|
||||
budgetId?: string,
|
||||
categoryId?: string,
|
||||
count?: number,
|
||||
from?: Date
|
||||
): Observable<Transaction[]> {
|
||||
|
@ -224,7 +227,7 @@ export class TwigsHttpService implements TwigsService {
|
|||
}));
|
||||
}
|
||||
|
||||
getTransaction(id: number): Observable<Transaction> {
|
||||
getTransaction(id: string): Observable<Transaction> {
|
||||
return this.http.get<Transaction>(`${this.apiUrl}/transactions/${id}`, this.options)
|
||||
.pipe(map(transaction => {
|
||||
transaction.date = new Date(transaction.date);
|
||||
|
@ -233,15 +236,17 @@ export class TwigsHttpService implements TwigsService {
|
|||
}
|
||||
|
||||
createTransaction(
|
||||
budgetId: number,
|
||||
id: string,
|
||||
budgetId: string,
|
||||
name: string,
|
||||
description: string,
|
||||
amount: number,
|
||||
date: Date,
|
||||
expense: boolean,
|
||||
category: number
|
||||
category: string
|
||||
): Observable<Transaction> {
|
||||
const params = {
|
||||
'id': id,
|
||||
'title': name,
|
||||
'description': description,
|
||||
'date': date.toISOString(),
|
||||
|
@ -253,11 +258,11 @@ export class TwigsHttpService implements TwigsService {
|
|||
return this.http.post<Transaction>(this.apiUrl + '/transactions', params, this.options);
|
||||
}
|
||||
|
||||
updateTransaction(budgetId: number, id: number, changes: object): Observable<Transaction> {
|
||||
updateTransaction(id: string, changes: object): Observable<Transaction> {
|
||||
return this.http.put<Transaction>(`${this.apiUrl}/transactions/${id}`, changes, this.options);
|
||||
}
|
||||
|
||||
deleteTransaction(budgetId: number, id: number): Observable<void> {
|
||||
deleteTransaction(id: string): Observable<void> {
|
||||
return this.http.delete<void>(`${this.apiUrl}/transactions/${id}`, this.options);
|
||||
}
|
||||
|
||||
|
@ -267,7 +272,7 @@ export class TwigsHttpService implements TwigsService {
|
|||
}
|
||||
|
||||
getUsersByUsername(username: string): Observable<User[]> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.error("Not yet implemented")
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import { TwigsService } from './twigs.service';
|
|||
import { Budget } from '../budgets/budget';
|
||||
import { Category } from '../categories/category';
|
||||
import { Transaction } from '../transactions/transaction';
|
||||
import { uuidv4 } from '../shared/utils';
|
||||
|
||||
/**
|
||||
* This is intended to be a very simple implementation of the TwigsService used for testing out the UI and quickly iterating on it.
|
||||
|
@ -20,14 +21,14 @@ export class TwigsLocalService implements TwigsService {
|
|||
private http: HttpClient
|
||||
) { }
|
||||
|
||||
private users: User[] = [new User(1, 'test', 'test@example.com')];
|
||||
private users: User[] = [new User(uuidv4(), 'test', 'test@example.com')];
|
||||
private budgets: Budget[] = [];
|
||||
private transactions: Transaction[] = [];
|
||||
private categories: Category[] = [];
|
||||
|
||||
// Auth
|
||||
login(email: string, password: string): Observable<User> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
const filteredUsers = this.users.filter(user => {
|
||||
return (user.email === email || user.username === email);
|
||||
});
|
||||
|
@ -40,11 +41,11 @@ export class TwigsLocalService implements TwigsService {
|
|||
}
|
||||
|
||||
register(username: string, email: string, password: string): Observable<User> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
const user = new User();
|
||||
user.username = username;
|
||||
user.email = email;
|
||||
user.id = this.users.length + 1;
|
||||
user.id = uuidv4();
|
||||
this.users.push(user);
|
||||
subscriber.next(user);
|
||||
subscriber.complete();
|
||||
|
@ -52,21 +53,21 @@ export class TwigsLocalService implements TwigsService {
|
|||
}
|
||||
|
||||
logout(): Observable<void> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.complete();
|
||||
});
|
||||
}
|
||||
|
||||
// Budgets
|
||||
getBudgets(): Observable<Budget[]> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.next(this.budgets);
|
||||
subscriber.complete();
|
||||
});
|
||||
}
|
||||
|
||||
getBudget(id: number): Observable<Budget> {
|
||||
return Observable.create(subscriber => {
|
||||
getBudget(id: string): Observable<Budget> {
|
||||
return new Observable(subscriber => {
|
||||
const budget = this.budgets.filter(it => {
|
||||
return it.id === id;
|
||||
})[0];
|
||||
|
@ -80,24 +81,25 @@ export class TwigsLocalService implements TwigsService {
|
|||
}
|
||||
|
||||
createBudget(
|
||||
id: string,
|
||||
name: string,
|
||||
description: string,
|
||||
users: UserPermission[],
|
||||
): Observable<Budget> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
const budget = new Budget();
|
||||
budget.name = name;
|
||||
budget.description = description;
|
||||
budget.users = users;
|
||||
budget.id = this.budgets.length + 1;
|
||||
budget.id = id;
|
||||
this.budgets.push(budget);
|
||||
subscriber.next(budget);
|
||||
subscriber.complete();
|
||||
});
|
||||
}
|
||||
|
||||
updateBudget(id: number, changes: object): Observable<Budget> {
|
||||
return Observable.create(subscriber => {
|
||||
updateBudget(id: string, changes: object): Observable<Budget> {
|
||||
return new Observable(subscriber => {
|
||||
const budget = this.budgets.filter(it => {
|
||||
return it.id === id;
|
||||
})[0];
|
||||
|
@ -121,8 +123,8 @@ export class TwigsLocalService implements TwigsService {
|
|||
});
|
||||
}
|
||||
|
||||
deleteBudget(id: number): Observable<void> {
|
||||
return Observable.create(subscriber => {
|
||||
deleteBudget(id: string): Observable<void> {
|
||||
return new Observable(subscriber => {
|
||||
const budget = this.budgets.filter(it => {
|
||||
return budget.id === id;
|
||||
})[0];
|
||||
|
@ -137,8 +139,8 @@ export class TwigsLocalService implements TwigsService {
|
|||
}
|
||||
|
||||
// Categories
|
||||
getCategories(budgetId: number, count?: number): Observable<Category[]> {
|
||||
return Observable.create(subscriber => {
|
||||
getCategories(budgetId: string, count?: number): Observable<Category[]> {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.next(this.categories.filter(category => {
|
||||
return category.budgetId === budgetId;
|
||||
}));
|
||||
|
@ -146,21 +148,21 @@ export class TwigsLocalService implements TwigsService {
|
|||
});
|
||||
}
|
||||
|
||||
getCategory(id: number): Observable<Category> {
|
||||
return Observable.create(subscriber => {
|
||||
getCategory(id: string): Observable<Category> {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.next(this.findById(this.categories, id));
|
||||
subscriber.complete();
|
||||
});
|
||||
}
|
||||
|
||||
getCategoryBalance(id: number): Observable<number> {
|
||||
getCategoryBalance(id: string): Observable<number> {
|
||||
return new Observable(emitter => {
|
||||
emitter.next(20);
|
||||
emitter.complete()
|
||||
})
|
||||
}
|
||||
|
||||
createCategory(budgetId: number, name: string, description: string, amount: number, isExpense: boolean): Observable<Category> {
|
||||
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Observable<Category> {
|
||||
return Observable.create(subscriber => {
|
||||
const category = new Category();
|
||||
category.title = name;
|
||||
|
@ -168,15 +170,15 @@ export class TwigsLocalService implements TwigsService {
|
|||
category.amount = amount;
|
||||
category.expense = isExpense;
|
||||
category.budgetId = budgetId;
|
||||
category.id = this.categories.length + 1;
|
||||
category.id = id;
|
||||
this.categories.push(category);
|
||||
subscriber.next(category);
|
||||
subscriber.complete();
|
||||
});
|
||||
}
|
||||
|
||||
updateCategory(budgetId: number, id: number, changes: object): Observable<Category> {
|
||||
return Observable.create(subscriber => {
|
||||
updateCategory(id: string, changes: object): Observable<Category> {
|
||||
return new Observable(subscriber => {
|
||||
const category = this.findById(this.categories, id);
|
||||
if (category) {
|
||||
const index = this.categories.indexOf(category);
|
||||
|
@ -199,8 +201,8 @@ export class TwigsLocalService implements TwigsService {
|
|||
});
|
||||
}
|
||||
|
||||
deleteCategory(budgetId: number, id: number): Observable<void> {
|
||||
return Observable.create(subscriber => {
|
||||
deleteCategory(id: string): Observable<void> {
|
||||
return new Observable(subscriber => {
|
||||
const category = this.findById(this.categories, id);
|
||||
if (category) {
|
||||
const index = this.categories.indexOf(category);
|
||||
|
@ -213,8 +215,8 @@ export class TwigsLocalService implements TwigsService {
|
|||
}
|
||||
|
||||
// Transactions
|
||||
getTransactions(budgetId?: number, categoryId?: number, count?: number): Observable<Transaction[]> {
|
||||
return Observable.create(subscriber => {
|
||||
getTransactions(budgetId?: string, categoryId?: string, count?: number): Observable<Transaction[]> {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.next(this.transactions.filter(transaction => {
|
||||
let include = true;
|
||||
if (budgetId) {
|
||||
|
@ -229,23 +231,24 @@ export class TwigsLocalService implements TwigsService {
|
|||
});
|
||||
}
|
||||
|
||||
getTransaction(id: number): Observable<Transaction> {
|
||||
return Observable.create(subscriber => {
|
||||
getTransaction(id: string): Observable<Transaction> {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.next(this.findById(this.transactions, id));
|
||||
subscriber.complete();
|
||||
});
|
||||
}
|
||||
|
||||
createTransaction(
|
||||
budgetId: number,
|
||||
id: string,
|
||||
budgetId: string,
|
||||
name: string,
|
||||
description: string,
|
||||
amount: number,
|
||||
date: Date,
|
||||
isExpense: boolean,
|
||||
category: number
|
||||
category: string
|
||||
): Observable<Transaction> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
const transaction = new Transaction();
|
||||
transaction.title = name;
|
||||
transaction.description = description;
|
||||
|
@ -254,15 +257,15 @@ export class TwigsLocalService implements TwigsService {
|
|||
transaction.expense = isExpense;
|
||||
transaction.categoryId = category;
|
||||
transaction.budgetId = budgetId;
|
||||
transaction.id = this.transactions.length + 1;
|
||||
transaction.id = uuidv4();
|
||||
this.transactions.push(transaction);
|
||||
subscriber.next(transaction);
|
||||
subscriber.complete();
|
||||
});
|
||||
}
|
||||
|
||||
updateTransaction(budgetId: number, id: number, changes: object): Observable<Transaction> {
|
||||
return Observable.create(subscriber => {
|
||||
updateTransaction(id: string, changes: object): Observable<Transaction> {
|
||||
return new Observable(subscriber => {
|
||||
const transaction = this.findById(this.transactions, id);
|
||||
if (transaction) {
|
||||
const index = this.transactions.indexOf(transaction);
|
||||
|
@ -289,8 +292,8 @@ export class TwigsLocalService implements TwigsService {
|
|||
});
|
||||
}
|
||||
|
||||
deleteTransaction(budgetId: number, id: number): Observable<void> {
|
||||
return Observable.create(subscriber => {
|
||||
deleteTransaction(id: string): Observable<void> {
|
||||
return new Observable(subscriber => {
|
||||
const transaction = this.findById(this.transactions, id);
|
||||
if (transaction) {
|
||||
const index = this.transactions.indexOf(transaction);
|
||||
|
@ -304,13 +307,13 @@ export class TwigsLocalService implements TwigsService {
|
|||
|
||||
// Users
|
||||
getProfile(): Observable<User> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.error("Not yet implemented")
|
||||
});
|
||||
}
|
||||
|
||||
getUsersByUsername(username: string): Observable<User[]> {
|
||||
return Observable.create(subscriber => {
|
||||
return new Observable(subscriber => {
|
||||
subscriber.next(this.users.filter(user => user.username.indexOf(username) > -1 ));
|
||||
});
|
||||
}
|
||||
|
@ -323,7 +326,7 @@ export class TwigsLocalService implements TwigsService {
|
|||
});
|
||||
}
|
||||
|
||||
private findById<T>(items: T[], id: number): T {
|
||||
private findById<T>(items: T[], id: string): T {
|
||||
return items.filter(item => {
|
||||
return item['id'] === id;
|
||||
})[0];
|
||||
|
|
|
@ -13,42 +13,44 @@ export interface TwigsService {
|
|||
|
||||
// Budgets
|
||||
getBudgets(): Observable<Budget[]>;
|
||||
getBudget(id: number): Observable<Budget>;
|
||||
getBudget(id: string): Observable<Budget>;
|
||||
createBudget(
|
||||
id: string,
|
||||
name: string,
|
||||
description: string,
|
||||
users: UserPermission[],
|
||||
): Observable<Budget>;
|
||||
updateBudget(id: number, changes: object): Observable<Budget>;
|
||||
deleteBudget(id: number): Observable<void>;
|
||||
updateBudget(id: string, changes: object): Observable<Budget>;
|
||||
deleteBudget(id: string): Observable<void>;
|
||||
|
||||
// Categories
|
||||
getCategories(budgetId?: number, count?: number): Observable<Category[]>;
|
||||
getCategory(id: number): Observable<Category>;
|
||||
getCategoryBalance(id: number): Observable<number>;
|
||||
createCategory(budgetId: number, name: string, description: string, amount: number, isExpense: boolean): Observable<Category>;
|
||||
updateCategory(budgetId: number, id: number, changes: object): Observable<Category>;
|
||||
deleteCategory(budgetId: number, id: number): Observable<void>;
|
||||
getCategories(budgetId?: string, count?: number): Observable<Category[]>;
|
||||
getCategory(id: string): Observable<Category>;
|
||||
getCategoryBalance(id: string): Observable<number>;
|
||||
createCategory(id: string, budgetId: string, name: string, description: string, amount: number, isExpense: boolean): Observable<Category>;
|
||||
updateCategory(id: string, changes: object): Observable<Category>;
|
||||
deleteCategory(id: string): Observable<void>;
|
||||
|
||||
// Transactions
|
||||
getTransactions(
|
||||
budgetId?: number,
|
||||
categoryId?: number,
|
||||
budgetId?: string,
|
||||
categoryId?: string,
|
||||
count?: number,
|
||||
from?: Date
|
||||
): Observable<Transaction[]>;
|
||||
getTransaction(id: number): Observable<Transaction>;
|
||||
getTransaction(id: string): Observable<Transaction>;
|
||||
createTransaction(
|
||||
budgetId: number,
|
||||
id: string,
|
||||
budgetId: string,
|
||||
name: string,
|
||||
description: string,
|
||||
amount: number,
|
||||
date: Date,
|
||||
isExpense: boolean,
|
||||
category: number
|
||||
category: string
|
||||
): Observable<Transaction>;
|
||||
updateTransaction(budgetId: number, id: number, changes: object): Observable<Transaction>;
|
||||
deleteTransaction(budgetId: number, id: number): Observable<void>;
|
||||
updateTransaction(id: string, changes: object): Observable<Transaction>;
|
||||
deleteTransaction(id: string): Observable<void>;
|
||||
|
||||
getProfile(): Observable<User>;
|
||||
getUsersByUsername(username: string): Observable<User[]>;
|
||||
|
|
6
src/app/shared/utils.ts
Normal file
6
src/app/shared/utils.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export function uuidv4(): string {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
|
@ -29,5 +29,5 @@
|
|||
</mat-select>
|
||||
</mat-form-field>
|
||||
<button mat-raised-button color="accent" (click)="save()">Save</button>
|
||||
<button class="button-delete" mat-raised-button color="warn" *ngIf="currentTransaction.id" (click)="delete()">Delete</button>
|
||||
<button class="button-delete" mat-raised-button color="warn" *ngIf="!create" (click)="delete()">Delete</button>
|
||||
</div>
|
||||
|
|
|
@ -14,7 +14,8 @@ import { MatRadioChange } from '@angular/material/radio';
|
|||
export class AddEditTransactionComponent implements OnInit, OnChanges {
|
||||
@Input() title: string;
|
||||
@Input() currentTransaction: Transaction;
|
||||
@Input() budgetId: number;
|
||||
@Input() budgetId: string;
|
||||
@Input() create: boolean
|
||||
public transactionType = TransactionType;
|
||||
public categories: Category[];
|
||||
public rawAmount: string;
|
||||
|
@ -48,15 +49,15 @@ export class AddEditTransactionComponent implements OnInit, OnChanges {
|
|||
}
|
||||
|
||||
const d = new Date(changes.currentTransaction.currentValue.date * 1000);
|
||||
this.transactionDate = d.toLocaleDateString(undefined, {year: 'numeric', month: '2-digit', day: '2-digit'});
|
||||
this.currentTime = d.toLocaleTimeString(undefined, {hour: '2-digit', hour12: false, minute: '2-digit'});
|
||||
this.transactionDate = d.toLocaleDateString(undefined, { year: 'numeric', month: '2-digit', day: '2-digit' });
|
||||
this.currentTime = d.toLocaleTimeString(undefined, { hour: '2-digit', hour12: false, minute: '2-digit' });
|
||||
}
|
||||
|
||||
updateCategories(change: MatRadioChange) {
|
||||
this.twigsService.getCategories(this.budgetId)
|
||||
.subscribe(newCategories => {
|
||||
this.categories = newCategories.filter(category => category.expense === change.value)
|
||||
})
|
||||
.subscribe(newCategories => {
|
||||
this.categories = newCategories.filter(category => category.expense === change.value)
|
||||
})
|
||||
}
|
||||
|
||||
save(): void {
|
||||
|
@ -71,10 +72,21 @@ export class AddEditTransactionComponent implements OnInit, OnChanges {
|
|||
const timeParts = this.currentTime.split(':');
|
||||
this.currentTransaction.date.setHours(parseInt(timeParts[0], 10));
|
||||
this.currentTransaction.date.setMinutes(parseInt(timeParts[1], 10));
|
||||
if (this.currentTransaction.id) {
|
||||
if (this.create) {
|
||||
// This is a new transaction, save it
|
||||
observable = this.twigsService.createTransaction(
|
||||
this.currentTransaction.id,
|
||||
this.budgetId,
|
||||
this.currentTransaction.title,
|
||||
this.currentTransaction.description,
|
||||
this.currentTransaction.amount * 100,
|
||||
this.currentTransaction.date,
|
||||
this.currentTransaction.expense,
|
||||
this.currentTransaction.categoryId,
|
||||
);
|
||||
} else {
|
||||
// This is an existing transaction, update it
|
||||
observable = this.twigsService.updateTransaction(
|
||||
this.budgetId,
|
||||
this.currentTransaction.id,
|
||||
{
|
||||
name: this.currentTransaction.title,
|
||||
|
@ -85,17 +97,6 @@ export class AddEditTransactionComponent implements OnInit, OnChanges {
|
|||
expense: this.currentTransaction.expense
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// This is a new transaction, save it
|
||||
observable = this.twigsService.createTransaction(
|
||||
this.budgetId,
|
||||
this.currentTransaction.title,
|
||||
this.currentTransaction.description,
|
||||
this.currentTransaction.amount * 100,
|
||||
this.currentTransaction.date,
|
||||
this.currentTransaction.expense,
|
||||
this.currentTransaction.categoryId,
|
||||
);
|
||||
}
|
||||
|
||||
observable.subscribe(val => {
|
||||
|
@ -104,7 +105,7 @@ export class AddEditTransactionComponent implements OnInit, OnChanges {
|
|||
}
|
||||
|
||||
delete(): void {
|
||||
this.twigsService.deleteTransaction(this.budgetId, this.currentTransaction.id).subscribe(() => {
|
||||
this.twigsService.deleteTransaction(this.currentTransaction.id).subscribe(() => {
|
||||
this.app.goBack();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
<app-add-edit-transaction [budgetId]="budgetId" [title]="'Add Transaction'" [currentTransaction]="transaction"></app-add-edit-transaction>
|
||||
<app-add-edit-transaction [budgetId]="budgetId" [title]="'Add Transaction'" [currentTransaction]="transaction" [create]="true"></app-add-edit-transaction>
|
||||
|
|
|
@ -1 +1 @@
|
|||
<app-add-edit-transaction [budgetId]="budgetId" [title]="'Edit Transaction'" [currentTransaction]="transaction" *ngIf="transaction"></app-add-edit-transaction>
|
||||
<app-add-edit-transaction [budgetId]="budgetId" [title]="'Edit Transaction'" [currentTransaction]="transaction" *ngIf="transaction" [create]="true"></app-add-edit-transaction>
|
||||
|
|
|
@ -10,7 +10,7 @@ import { TWIGS_SERVICE, TwigsService } from 'src/app/shared/twigs.service';
|
|||
})
|
||||
export class TransactionDetailsComponent implements OnInit {
|
||||
|
||||
budgetId: number;
|
||||
budgetId: string;
|
||||
transaction: Transaction;
|
||||
|
||||
constructor(
|
||||
|
@ -23,7 +23,7 @@ export class TransactionDetailsComponent implements OnInit {
|
|||
}
|
||||
|
||||
getTransaction(): void {
|
||||
const id = Number.parseInt(this.route.snapshot.paramMap.get('id'));
|
||||
const id = this.route.snapshot.paramMap.get('id');
|
||||
this.twigsService.getTransaction(id)
|
||||
.subscribe(transaction => {
|
||||
transaction.amount /= 100;
|
||||
|
|
|
@ -9,8 +9,8 @@ import { TWIGS_SERVICE, TwigsService } from '../../shared/twigs.service';
|
|||
})
|
||||
export class TransactionListComponent implements OnInit {
|
||||
|
||||
@Input() budgetId: number;
|
||||
@Input() categoryId?: number;
|
||||
@Input() budgetId: string;
|
||||
@Input() categoryId?: string;
|
||||
public transactions: Transaction[];
|
||||
|
||||
constructor(
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { uuidv4 } from '../shared/utils';
|
||||
|
||||
export class Transaction {
|
||||
id: number;
|
||||
id: string = uuidv4();
|
||||
title: string;
|
||||
description: string = null;
|
||||
date: Date = new Date();
|
||||
amount: number;
|
||||
expense = true;
|
||||
categoryId: number;
|
||||
budgetId: number;
|
||||
createdBy: number;
|
||||
categoryId: string;
|
||||
budgetId: string;
|
||||
createdBy: string;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { uuidv4 } from "../shared/utils";
|
||||
|
||||
export class User {
|
||||
id: number;
|
||||
id: string = uuidv4();
|
||||
username: string;
|
||||
email: string;
|
||||
|
||||
constructor(id?: number, username?: string, email?: string) {
|
||||
constructor(id?: string, username?: string, email?: string) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.email = email;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const environment = {
|
||||
production: false,
|
||||
apiUrl: 'https://3000code.brawner.home'
|
||||
apiUrl: 'https://3000code.wbrawner.com'
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue