feat: replace CreateComponent with FormComponent in app

This commit is contained in:
2025-06-24 08:40:02 +02:00
parent 471e86d223
commit 943a011185
15 changed files with 90 additions and 164 deletions

View File

@ -1,5 +1,5 @@
<app-create />
<app-form [todo]="ref.editingTodo" />
<app-table />
<app-table #ref />
<router-outlet />

View File

@ -1,29 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have the 'todo' title`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('todo');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, todo');
});
});

View File

@ -1,15 +1,14 @@
import {Component} from '@angular/core';
import {RouterOutlet} from '@angular/router';
import {TableComponent} from "./table/table.component";
import {CreateComponent} from "./create/create.component";
import {FormComponent} from "./form/form.component";
@Component({
selector: 'app-root',
imports: [RouterOutlet, TableComponent, CreateComponent],
imports: [RouterOutlet, TableComponent, FormComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.css',
standalone: true,
})
export class AppComponent {
title = 'todo';
}

View File

@ -1,6 +0,0 @@
<form [formGroup]="this.form">
<input type="text" formControlName="title">
<input type="date" formControlName="dueDate">
<button type="submit" (click)="create()">Save </button>
</form>

View File

@ -1,32 +0,0 @@
import {Component, inject, OnInit} from '@angular/core';
import {TodoService} from "../service/todo.service";
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
@Component({
selector: 'app-create',
standalone: true,
imports: [
ReactiveFormsModule
],
templateUrl: './create.component.html',
styleUrl: './create.component.css'
})
export class CreateComponent implements OnInit {
todoService: TodoService = inject(TodoService);
formBuilder: FormBuilder = inject(FormBuilder);
form!: FormGroup;
ngOnInit(): void {
this.form = this.formBuilder.group({
title: ['', Validators.required],
dueDate: ['', Validators.required],
})
}
public create(): void {
this.todoService.create(this.form.value).subscribe(() => {
this.todoService.todos.reload();
this.form.reset();
})
}
}

View File

@ -1,4 +1,4 @@
interface GetTask {
interface Todo {
id: number;
title: string;
done: boolean;
@ -13,4 +13,4 @@ interface PutTask {
done: boolean;
}
export { GetTask, PutTask };
export { Todo, PutTask };

View File

@ -1,6 +0,0 @@
<form [formGroup]="form">
<input type="text" formControlName="title">
<input type="date" formControlName="dueDate">
<button type="submit" (click)="edit()">Save</button>
</form>

View File

@ -1,45 +0,0 @@
import {Component, computed, effect, inject, input, InputSignal, OnInit, Signal, WritableSignal} from '@angular/core';
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
import {GetTask} from "../dto/models";
import {TodoService} from "../service/todo.service";
import {DatePipe} from "@angular/common";
@Component({
selector: 'app-edit',
imports: [
ReactiveFormsModule
],
templateUrl: './edit.component.html',
standalone: true,
styleUrl: './edit.component.css'
})
export default class EditComponent implements OnInit{
private fb: FormBuilder = inject(FormBuilder);
private todoService: TodoService = inject(TodoService);
public form!: FormGroup;
public todo: InputSignal<GetTask|null> = input<GetTask|null>(null);
public kys = effect(() => {
console.log(this.todo())
});
constructor() {
effect(() => {
this.form = this.fb.group({
title: [this.todo()?.title, Validators.required],
dueDate: [new DatePipe('en-US').transform(this.todo()?.dueDate, 'yyyy-MM-dd'), Validators.required],
})
});
}
ngOnInit() {
}
edit() {
const edited = {
...this.todo(),
...this.form.value,
}
this.todoService.edit(edited, this.todo()?.id ?? 0).subscribe(() => this.todoService.todos.reload())
}
}

View File

@ -0,0 +1,7 @@
<form [formGroup]="form">
<input type="text" required formControlName="title">
<input type="date" required formControlName="dueDate">
<button (click)="save()">Save</button>
<button (click)="clear()">Clear</button>
</form>

View File

@ -0,0 +1,49 @@
import {Component, effect, inject, model} from '@angular/core';
import {Todo} from "../dto/models";
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
import {DatePipe} from "@angular/common";
import {TodoService} from "../service/todo.service";
@Component({
selector: 'app-form',
imports: [
ReactiveFormsModule
],
templateUrl: './form.component.html',
standalone: true,
styleUrl: './form.component.css'
})
export class FormComponent {
todo = model<Todo|null>(null);
form!: FormGroup;
fb: FormBuilder = inject(FormBuilder);
todoService: TodoService = inject(TodoService);
constructor() {
effect(() => {
this.form = this.fb.group({
title: [this.todo()?.title ?? '', Validators.required],
dueDate: [new DatePipe('en-US').transform(this.todo()?.dueDate ?? '', 'yyyy-MM-dd')],
});
});
}
save() {
const id = this.todo()?.id;
let subscription;
if (id) {
subscription = this.todoService.edit({...this.todo(),...this.form.value}, id);
} else {
subscription = this.todoService.create({...this.form.value, done: false});
}
subscription.subscribe(() => this.todoService.todos.reload());
}
clear() {
this.form.reset();
this.todo.set(null);
}
}

View File

@ -1,7 +1,6 @@
import {inject, Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {Observable} from "rxjs";
import {GetTask, PutTask} from "../dto/models";
import {Todo} from "../dto/models";
import {rxResource} from "@angular/core/rxjs-interop";
@ -12,22 +11,18 @@ export class TodoService {
http: HttpClient = inject(HttpClient);
_todos = rxResource({
stream: () => this.getTodos(),
stream: () => this.http.get<Todo[]>('http://localhost:2000/api/tasks'),
})
public get todos() {
return this._todos;
}
public getTodos(): Observable<GetTask[]> {
return this.http.get<GetTask[]>('http://localhost:2000/api/tasks');
}
public create(todo: { title: string, dueDate: Date }) {
public create(todo: Todo) {
return this.http.post('http://localhost:2000/api/tasks', todo);
}
public toggleDone(todo: GetTask) {
public toggleDone(todo: Todo) {
todo.done = !todo.done;
return this.edit(todo, todo.id);
@ -37,7 +32,7 @@ export class TodoService {
return this.http.delete(`http://localhost:2000/api/tasks/${id}`);
}
edit(edited: GetTask, id: number) {
public edit(edited: Todo, id: number) {
return this.http.put(`http://localhost:2000/api/tasks/${id}`, edited);
}
}

View File

@ -31,7 +31,3 @@
}
</tbody>
</table>
@if (editingTodo() !== null) {
<app-edit [todo]="editingTodo()" />
}

View File

@ -1,15 +1,13 @@
import {Component, inject, signal, WritableSignal} from '@angular/core';
import {Component, effect, EventEmitter, inject, signal, Signal, WritableSignal} from '@angular/core';
import {TodoService} from "../service/todo.service";
import {DatePipe} from "@angular/common";
import {GetTask} from "../dto/models";
import EditComponent from "../edit/edit.component";
import {Todo} from "../dto/models";
@Component({
selector: 'app-table',
standalone: true,
imports: [
DatePipe,
EditComponent,
],
templateUrl: './table.component.html',
styleUrl: './table.component.css'
@ -17,9 +15,9 @@ import EditComponent from "../edit/edit.component";
export class TableComponent {
todoService: TodoService = inject(TodoService);
todos = this.todoService.todos;
editingTodo: WritableSignal<GetTask|null> = signal(null);
editingTodo: Todo|null = null;
toggleDone(todo: GetTask) {
toggleDone(todo: Todo) {
this.todoService.toggleDone(todo).subscribe(() => this.todos.reload());
}
@ -27,7 +25,7 @@ export class TableComponent {
this.todoService.delete(id).subscribe(() => this.todos.reload());
}
edit(todo: GetTask) {
this.editingTodo.set(todo);
edit(todo: Todo) {
this.editingTodo = todo;
}
}