break expense component into smaller pieces
This commit is contained in:
parent
e127b8ec45
commit
2ca674c3bb
18 changed files with 197 additions and 389 deletions
|
|
@ -1,131 +1,73 @@
|
|||
import { Component, computed, input, signal } from '@angular/core';
|
||||
import { Category, CategoryService } from '../../services/category.service';
|
||||
import { Merchant, MerchantService } from '../../services/merchant.service';
|
||||
import { Tag, TagService } from '../../services/tag.service';
|
||||
import { form, FormField, min, required } from '@angular/forms/signals';
|
||||
import { Component, input, model, signal } from '@angular/core';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { provideNativeDateAdapter } from '@angular/material/core';
|
||||
import { CreateExpense, Expense, ExpenseService } from '../../services/expense.service';
|
||||
import { CurrencyPipe, DatePipe } from '@angular/common';
|
||||
import { Expense, ExpenseService } from '../../services/expense.service';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { Temporal } from '@js-temporal/polyfill';
|
||||
// import { MatChip } from '@angular/material/chips';
|
||||
|
||||
interface ExpenseForm {
|
||||
date: Date | string;
|
||||
cents: number;
|
||||
category: Category | string;
|
||||
merchant: Merchant | string;
|
||||
note: string;
|
||||
tags: Tag[];
|
||||
}
|
||||
import { ExpenseFormComponent } from './expense-form/expense-form.component';
|
||||
import { CurrencyPipe, DatePipe } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-expense',
|
||||
imports: [
|
||||
MatDatepickerModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatCardModule,
|
||||
MatAutocompleteModule,
|
||||
MatSelectModule,
|
||||
MatButtonModule,
|
||||
FormField,
|
||||
DatePipe,
|
||||
MatIcon,
|
||||
CurrencyPipe,
|
||||
// MatChip
|
||||
],
|
||||
providers: [provideNativeDateAdapter(), DatePipe],
|
||||
imports: [MatCardModule, MatButtonModule, MatIcon, ExpenseFormComponent, DatePipe, CurrencyPipe],
|
||||
providers: [],
|
||||
templateUrl: './expense.component.html',
|
||||
styleUrl: './expense.component.scss',
|
||||
})
|
||||
export class ExpenseComponent {
|
||||
public expense = input<Expense>();
|
||||
protected expenseMode = signal<'view' | 'edit'>('view');
|
||||
protected state = computed<'add' | 'view' | 'edit'>(() => this.expense() ? this.expenseMode() : 'add');
|
||||
protected saving = signal(false);
|
||||
protected categories = computed(() => this.categoryService.categories());
|
||||
protected merchants = computed(() => this.merchantService.merchants());
|
||||
protected tags = computed(() => this.tagService.tags());
|
||||
protected enableSaveButton = computed(() => {
|
||||
const dateValid = this.expenseForm.date().valid();
|
||||
const centsValid = this.expenseForm.cents().valid();
|
||||
const categoryValid = this.expenseForm.category().valid();
|
||||
const merchantValid = this.expenseForm.merchant().valid();
|
||||
const noteValid = this.expenseForm.note().valid();
|
||||
|
||||
return dateValid && centsValid && categoryValid && merchantValid && noteValid && !this.saving();
|
||||
});
|
||||
public editingExpense = signal(false);
|
||||
public formValid = model(false);
|
||||
public formDirty = model(false);
|
||||
|
||||
// private lastSelectedDate: Date | undefined;
|
||||
// private expenseDate = computed(() => {
|
||||
// return this.expense()
|
||||
// ? new Date(`${this.expense()?.year}-${this.expense()?.month}-${this.expense()?.day}`)
|
||||
// : this.lastSelectedDate ?? '';
|
||||
// });
|
||||
private defaultForm: ExpenseForm = {
|
||||
date: '',
|
||||
cents: this.expense()?.cents ?? NaN,
|
||||
category: this.expense()?.category ?? '',
|
||||
merchant: this.expense()?.merchant ?? '',
|
||||
note: this.expense()?.note ?? '',
|
||||
tags: this.expense()?.tags ?? []
|
||||
};
|
||||
private expenseModel = signal<ExpenseForm>(this.defaultForm);
|
||||
public expenseForm = form(this.expenseModel, (schema) => {
|
||||
required(schema.date);
|
||||
required(schema.cents);
|
||||
min(schema.cents, 1);
|
||||
required(schema.category);
|
||||
});
|
||||
|
||||
public constructor(private readonly categoryService: CategoryService,
|
||||
private readonly merchantService: MerchantService,
|
||||
private readonly tagService: TagService,
|
||||
private readonly expenseService: ExpenseService,
|
||||
private readonly datePipe: DatePipe) { }
|
||||
|
||||
public async saveClick(): Promise<void> {
|
||||
// const saveExpenseModel = this.expenseModel();
|
||||
// const date = this.datePipe.transform(saveExpenseModel.date, 'yyyy-MM-dd')?.split('-') ?? [];
|
||||
// const expense: CreateExpense = {
|
||||
// year: date[0],
|
||||
// month: date[1],
|
||||
// day: date[2],
|
||||
// cents: saveExpenseModel.cents,
|
||||
// category: saveExpenseModel.category as Category,
|
||||
// merchant: saveExpenseModel.merchant ? saveExpenseModel.merchant as Merchant : undefined,
|
||||
// note: saveExpenseModel.note ? saveExpenseModel.note : undefined,
|
||||
// tags: saveExpenseModel.tags
|
||||
// };
|
||||
//
|
||||
// this.saving.set(true);
|
||||
// try {
|
||||
// await this.expenseService.postExpense(expense);
|
||||
// this.lastSelectedDate = saveExpenseModel.date ? saveExpenseModel.date as Date : undefined;
|
||||
// this.expenseModel.set({ ...this.defaultForm, date: saveExpenseModel.date });
|
||||
// this.expenseForm().reset(this.expenseModel());
|
||||
// }
|
||||
// catch (error) {
|
||||
// console.error(error);
|
||||
// }
|
||||
// finally {
|
||||
// this.saving.set(false);
|
||||
// }
|
||||
}
|
||||
public constructor(private readonly expenseService: ExpenseService) { }
|
||||
|
||||
public editClick(): void {
|
||||
this.expenseMode.set('edit');
|
||||
this.editingExpense.set(true);
|
||||
}
|
||||
|
||||
public autocompleteDisplay(value: Merchant | Category) {
|
||||
return value.name ?? null;
|
||||
public async addClick(): Promise<void> {
|
||||
console.log('Adding new expense');
|
||||
}
|
||||
|
||||
public resetAddClick(): void {
|
||||
console.log('Reset Add expense form');
|
||||
}
|
||||
|
||||
public async updateClick(): Promise<void> {
|
||||
console.log('Updating expense')
|
||||
this.editingExpense.set(false);
|
||||
}
|
||||
|
||||
public cancelUpdateClick(): void {
|
||||
console.log('Canceling update');
|
||||
this.editingExpense.set(false);
|
||||
}
|
||||
|
||||
// const saveExpenseModel = this.expenseModel();
|
||||
// const date = this.datePipe.transform(saveExpenseModel.date, 'yyyy-MM-dd')?.split('-') ?? [];
|
||||
// const expense: CreateExpense = {
|
||||
// year: date[0],
|
||||
// month: date[1],
|
||||
// day: date[2],
|
||||
// cents: saveExpenseModel.cents,
|
||||
// category: saveExpenseModel.category as Category,
|
||||
// merchant: saveExpenseModel.merchant ? saveExpenseModel.merchant as Merchant : undefined,
|
||||
// note: saveExpenseModel.note ? saveExpenseModel.note : undefined,
|
||||
// tags: saveExpenseModel.tags
|
||||
// };
|
||||
//
|
||||
// this.saving.set(true);
|
||||
// try {
|
||||
// await this.expenseService.postExpense(expense);
|
||||
// this.lastSelectedDate = saveExpenseModel.date ? saveExpenseModel.date as Date : undefined;
|
||||
// this.expenseModel.set({ ...this.defaultForm, date: saveExpenseModel.date });
|
||||
// this.expenseForm().reset(this.expenseModel());
|
||||
// }
|
||||
// catch (error) {
|
||||
// console.error(error);
|
||||
// }
|
||||
// finally {
|
||||
// this.saving.set(false);
|
||||
// }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue