metadata-management #10

Merged
joe merged 18 commits from metadata-management into master 2026-02-26 18:35:33 +00:00
9 changed files with 75 additions and 51 deletions
Showing only changes of commit 3d0d63b1d4 - Show all commits

View file

@ -46,8 +46,8 @@ export class ExpenseComponent {
this.savingExpense.set(true);
const snackId = this.snackBar.staticBar('Tracking new expense...');
try {
await this.expenseService.postExpense(postExpense);
await this.expenseService.fetchExpenses();
await this.expenseService.create(postExpense);
await this.expenseService.fetch();
this.resetForm();
this.snackBar.dismiss(snackId);
this.snackBar.autoBar('Expense tracked!');
@ -79,7 +79,7 @@ export class ExpenseComponent {
this.savingExpense.set(true);
const snackId = this.snackBar.staticBar('Updating expense...');
try {
const expense = await this.expenseService.updateExpense(putExpense);
const expense = await this.expenseService.update(putExpense);
this.expense.set(expense);
this.form()?.refresh(expense);
this.editingExpense.set(false);

View file

@ -18,12 +18,12 @@ export class CategoriesComponent {
public constructor(private readonly categoryService: CategoryService) { }
public async createCategory(name: string): Promise<void> {
await this.categoryService.createCategory({ name });
await this.categoryService.fetchCategories();
await this.categoryService.create({ name });
await this.categoryService.fetch();
}
public async updateCategory(category: Category): Promise<void> {
await this.categoryService.updateCategory(category);
await this.categoryService.fetchCategories();
await this.categoryService.update(category);
await this.categoryService.fetch();
}
}

View file

@ -1,17 +1,24 @@
<div class="merchants-container">
<div class="merchant-list-header">
<p>Merchants</p>
<app-divider />
</div>
<mat-card appearance="outlined">
<mat-card-header>
<mat-card-title>Merchants</mat-card-title>
</mat-card-header>
<div class="merchant-list">
@for (merchant of merchants(); track merchant.id) {
<div>{{ merchant.name }}</div>
}
@if (!merchants().length) {
<div class="merchant-list-empty">
No merchants to display
<mat-card-content>
<div class="new-merchant">
<app-metadata-form (newMetaData)="createMerchant($event.name)" [editing]="true" [label]="'New Merchant'"/>
</div>
}
</div>
<div class="merchant-list">
@for (merchant of merchants(); track merchant.id) {
<app-metadata-form [metadata]="merchant" (newMetaData)="updateMerchant($event)" />
}
@if (!merchants().length) {
<div>
No merchants to display
</div>
}
</div>
</mat-card-content>
</mat-card>
</div>

View file

@ -1,28 +1,21 @@
.merchants-container {
display: grid;
gap: 1rem;
}
@use "variables";
.merchant-list-header {
padding-top: 1rem;
.merchants-container {
padding-top: 0.5rem;
display: flex;
flex-direction: column;
align-items: center;
p {
font-size: 1.8rem;
line-height: 100%;
font-weight: 400;
margin: 0;
}
app-divider {
mat-card {
max-width: variables.$wide-screen;
width: 100%;
}
}
.new-merchant {
padding-top: 0.5rem;
}
.merchant-list {
display: grid;
gap: 1rem;
justify-content: center;
}

View file

@ -1,11 +1,13 @@
import { Component, computed } from '@angular/core';
import { MerchantService } from '../../../services/merchant.service';
import { DividerComponent } from '../../divider/divider.component';
import { Merchant, MerchantService } from '../../../services/merchant.service';
import { MatCardModule } from '@angular/material/card';
import { MetadataFormComponent } from '../metadata-form/metadata-form.component';
@Component({
selector: 'app-merchants',
imports: [
DividerComponent
MatCardModule,
MetadataFormComponent
],
templateUrl: './merchants.component.html',
styleUrl: './merchants.component.scss'
@ -14,4 +16,14 @@ export class MerchantsComponent {
protected merchants = computed(() => this.merchantService.merchants());
public constructor(private readonly merchantService: MerchantService) { }
public async createMerchant(name: string): Promise<void> {
await this.merchantService.create({ name });
await this.merchantService.fetch();
}
public async updateMerchant(merchant: Merchant): Promise<void> {
await this.merchantService.update(merchant);
await this.merchantService.fetch();
}
}

View file

@ -10,18 +10,18 @@ export class CategoryService {
public readonly categoryPath = 'http://localhost:3000/common-cents/categories';
public constructor(private readonly http: HttpService) {
void this.fetchCategories();
void this.fetch();
}
public async fetchCategories(): Promise<void> {
public async fetch(): Promise<void> {
this.internalCategories.set(await this.http.get<Category[]>(this.categoryPath));
}
public async createCategory(category: CreateCategory): Promise<Category> {
public async create(category: CreateCategory): Promise<Category> {
return await this.http.post<Category>(this.categoryPath, category);
}
public async updateCategory(category: Category): Promise<Category> {
public async update(category: Category): Promise<Category> {
return await this.http.put<Category>(this.categoryPath, category);
}
}

View file

@ -14,18 +14,18 @@ export class ExpenseService {
public readonly expensePath = 'http://localhost:3000/common-cents/expenses'; // TODO: refactor
public constructor(private readonly http: HttpService) {
void this.fetchExpenses();
void this.fetch();
}
public async fetchExpenses(): Promise<void> {
public async fetch(): Promise<void> {
this.internalExpenses.set(await this.http.get(this.expensePath));
}
public async postExpense(createExpense: CreateExpense): Promise<Expense> {
public async create(createExpense: CreateExpense): Promise<Expense> {
return await this.http.post<Expense>(this.expensePath, createExpense);
}
public async updateExpense(updateExpense: UpdateExpense): Promise<Expense> {
public async update(updateExpense: UpdateExpense): Promise<Expense> {
return await this.http.put<Expense>(this.expensePath, updateExpense);
}
}

View file

@ -10,15 +10,27 @@ export class MerchantService {
public readonly merchantPath = 'http://localhost:3000/common-cents/merchants';
public constructor(private readonly http: HttpService) {
void this.fetchMerchants();
void this.fetch();
}
public async fetchMerchants(): Promise<void> {
public async fetch(): Promise<void> {
this.internalMerchants.set(await this.http.get<Merchant[]>(this.merchantPath));
}
public async create(merchant: CreateMerchant): Promise<Merchant> {
return await this.http.post<Merchant>(this.merchantPath, merchant);
}
public async update(merchant: Merchant): Promise<Merchant> {
return await this.http.put<Merchant>(this.merchantPath, merchant);
}
}
export interface Merchant {
id: string;
name: string;
}
export interface CreateMerchant {
name: string;
}

View file

@ -10,10 +10,10 @@ export class TagService {
public readonly tagPath = 'http://localhost:3000/common-cents/tags';
public constructor(private readonly http: HttpService) {
void this.fetchTags();
void this.fetch();
}
public async fetchTags(): Promise<void> {
public async fetch(): Promise<void> {
this.internalTags.set(await this.http.get<Tag[]>(this.tagPath));
}
}