diff --git a/src/app/components/expense/expense-form/expense-form.component.ts b/src/app/components/expense/expense-form/expense-form.component.ts index 02b93c5..07bc3a6 100644 --- a/src/app/components/expense/expense-form/expense-form.component.ts +++ b/src/app/components/expense/expense-form/expense-form.component.ts @@ -10,7 +10,7 @@ import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { provideNativeDateAdapter } from '@angular/material/core'; -interface ExpenseForm { +export interface ExpenseForm { date: Date; cents: number; category: Category; @@ -29,14 +29,13 @@ interface ExpenseForm { export class ExpenseFormComponent implements OnInit { public expense = input(); public disabled = input(false); - public valid = output(); public dirty = output() - public value = output(); + public value = output(); + private lastDate = signal(undefined); private formValid = computed(() => this.form().valid() && this.form().dirty()); - private formDirty = computed(() => this.form().dirty() && this.form().touched()); - private lastSelectedDate = signal(undefined); + private formDirty = computed(() => this.form().dirty() || this.form().touched()); private formData = computed(() => this.buildForm(this.expense())); private formModel = signal(this.formData()); @@ -46,18 +45,30 @@ export class ExpenseFormComponent implements OnInit { protected form = form(this.formModel, this.buildFormOptions()); constructor(private readonly categoryService: CategoryService, - private readonly merchantService: MerchantService, - private readonly tagService: TagService) { + private readonly merchantService: MerchantService, + private readonly tagService: TagService) { effect(() => { - this.valid.emit(this.formValid()); - this.dirty.emit(this.formDirty()); + const valid = this.formValid(); + const dirty = this.formDirty(); + const value = this.form().value(); + + this.valid.emit(valid); + this.dirty.emit(dirty); + this.value.emit(value); + this.lastDate.set(value.date); }); } public ngOnInit(): void { - console.log({ expense: this.expense() }); + this.reset(); + } + + public reset(clearDate = false): void { + if (clearDate) { + this.lastDate.set(undefined); + this.form().reset(); + } this.formModel.set(this.formData()); - this.form().reset(); } public autocompleteDisplay(value: Merchant | Category) { @@ -65,7 +76,7 @@ export class ExpenseFormComponent implements OnInit { } private buildForm(expense?: Expense): ExpenseForm { - let formData = { date: this.lastSelectedDate() ?? '', cents: '', category: '', merchant: '', note: '', tags: ''} as unknown as ExpenseForm + let formData = { date: this.lastDate() ?? '', cents: NaN, category: {}, merchant: {}, note: '', tags: [] } as unknown as ExpenseForm if (expense) { formData = { date: new Date(expense.date.toString()), @@ -76,6 +87,7 @@ export class ExpenseFormComponent implements OnInit { tags: expense.tags ?? [] } as ExpenseForm; } + return formData; } diff --git a/src/app/components/expense/expense.component.html b/src/app/components/expense/expense.component.html index b3916d4..e6c6cdd 100644 --- a/src/app/components/expense/expense.component.html +++ b/src/app/components/expense/expense.component.html @@ -21,9 +21,10 @@ + (dirty)="formDirty.set($event)" + (value)="formData.set($event)" /> diff --git a/src/app/components/expense/expense.component.ts b/src/app/components/expense/expense.component.ts index 52fa70a..32f28a8 100644 --- a/src/app/components/expense/expense.component.ts +++ b/src/app/components/expense/expense.component.ts @@ -1,10 +1,11 @@ -import { Component, input, model, signal } from '@angular/core'; +import { Component, input, model, signal, viewChild } from '@angular/core'; import { MatCardModule } from '@angular/material/card'; import { MatButtonModule } from '@angular/material/button'; -import { Expense, ExpenseService } from '../../services/expense.service'; +import { CreateExpense, Expense, ExpenseService, UpdateExpense } from '../../services/expense.service'; import { MatIcon } from '@angular/material/icon'; -import { ExpenseFormComponent } from './expense-form/expense-form.component'; +import { ExpenseForm, ExpenseFormComponent } from './expense-form/expense-form.component'; import { CurrencyPipe, DatePipe } from '@angular/common'; +import { Temporal } from '@js-temporal/polyfill'; @Component({ selector: 'app-expense', @@ -14,11 +15,15 @@ import { CurrencyPipe, DatePipe } from '@angular/common'; styleUrl: './expense.component.scss', }) export class ExpenseComponent { + private form = viewChild(ExpenseFormComponent); public expense = input(); public editingExpense = signal(false); + public savingExpense = signal(false); + public formValid = model(false); public formDirty = model(false); + public formData = model(); public constructor(private readonly expenseService: ExpenseService) { } @@ -27,20 +32,46 @@ export class ExpenseComponent { } public async addClick(): Promise { - console.log('Adding new expense'); + const form = this.formData()!; + const postExpense: CreateExpense = { + date: new Temporal.PlainDate(form.date.getFullYear(), form.date.getMonth(), form.date.getDate()), + cents: form.cents, + categoryId: form.category.id, + note: !!form.note ? form.note : undefined, + merchantId: !!form.merchant ? form.merchant.id : undefined, + tagIds: form.tags.map(tag => tag.id) + }; + await this.expenseService.postExpense(postExpense); + this.resetForm(); } public resetAddClick(): void { - console.log('Reset Add expense form'); + this.resetForm(true); } public async updateClick(): Promise { - console.log('Updating expense') - this.editingExpense.set(false); + const form = this.formData()!; + const updateExpense: UpdateExpense = { + id: this.expense()!.id, + date: Temporal.PlainDate.from(form.date.toString()), + cents: form.cents, + categoryId: form.category.id, + note: !!form.note ? form.note : undefined, + merchantId: !!form.merchant ? form.merchant.id : undefined, + tagIds: form.tags.map(tag => tag.id) + }; + console.log('update:', updateExpense); + // post update dto + // set expense + this.resetForm(); } public cancelUpdateClick(): void { - console.log('Canceling update'); + this.resetForm(); + } + + private resetForm(clearDate = false): void { + this.form()?.reset(clearDate); this.editingExpense.set(false); }