feat: replace CreateComponent with FormComponent in app
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<app-create />
|
<app-form [todo]="ref.editingTodo" />
|
||||||
|
|
||||||
<app-table />
|
<app-table #ref />
|
||||||
|
|
||||||
<router-outlet />
|
<router-outlet />
|
||||||
|
@ -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');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,15 +1,14 @@
|
|||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {RouterOutlet} from '@angular/router';
|
import {RouterOutlet} from '@angular/router';
|
||||||
import {TableComponent} from "./table/table.component";
|
import {TableComponent} from "./table/table.component";
|
||||||
import {CreateComponent} from "./create/create.component";
|
import {FormComponent} from "./form/form.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [RouterOutlet, TableComponent, CreateComponent],
|
imports: [RouterOutlet, TableComponent, FormComponent],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.css',
|
styleUrl: './app.component.css',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'todo';
|
|
||||||
}
|
}
|
||||||
|
@ -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>
|
|
||||||
|
|
@ -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();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
interface GetTask {
|
interface Todo {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
done: boolean;
|
done: boolean;
|
||||||
@ -13,4 +13,4 @@ interface PutTask {
|
|||||||
done: boolean;
|
done: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { GetTask, PutTask };
|
export { Todo, PutTask };
|
||||||
|
@ -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>
|
|
@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
7
frontend/src/app/form/form.component.html
Normal file
7
frontend/src/app/form/form.component.html
Normal 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>
|
||||||
|
|
49
frontend/src/app/form/form.component.ts
Normal file
49
frontend/src/app/form/form.component.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
import {inject, Injectable} from "@angular/core";
|
import {inject, Injectable} from "@angular/core";
|
||||||
import {HttpClient} from "@angular/common/http";
|
import {HttpClient} from "@angular/common/http";
|
||||||
import {Observable} from "rxjs";
|
import {Todo} from "../dto/models";
|
||||||
import {GetTask, PutTask} from "../dto/models";
|
|
||||||
import {rxResource} from "@angular/core/rxjs-interop";
|
import {rxResource} from "@angular/core/rxjs-interop";
|
||||||
|
|
||||||
|
|
||||||
@ -12,22 +11,18 @@ export class TodoService {
|
|||||||
http: HttpClient = inject(HttpClient);
|
http: HttpClient = inject(HttpClient);
|
||||||
|
|
||||||
_todos = rxResource({
|
_todos = rxResource({
|
||||||
stream: () => this.getTodos(),
|
stream: () => this.http.get<Todo[]>('http://localhost:2000/api/tasks'),
|
||||||
})
|
})
|
||||||
|
|
||||||
public get todos() {
|
public get todos() {
|
||||||
return this._todos;
|
return this._todos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTodos(): Observable<GetTask[]> {
|
public create(todo: Todo) {
|
||||||
return this.http.get<GetTask[]>('http://localhost:2000/api/tasks');
|
|
||||||
}
|
|
||||||
|
|
||||||
public create(todo: { title: string, dueDate: Date }) {
|
|
||||||
return this.http.post('http://localhost:2000/api/tasks', todo);
|
return this.http.post('http://localhost:2000/api/tasks', todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleDone(todo: GetTask) {
|
public toggleDone(todo: Todo) {
|
||||||
todo.done = !todo.done;
|
todo.done = !todo.done;
|
||||||
|
|
||||||
return this.edit(todo, todo.id);
|
return this.edit(todo, todo.id);
|
||||||
@ -37,7 +32,7 @@ export class TodoService {
|
|||||||
return this.http.delete(`http://localhost:2000/api/tasks/${id}`);
|
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);
|
return this.http.put(`http://localhost:2000/api/tasks/${id}`, edited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,3 @@
|
|||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@if (editingTodo() !== null) {
|
|
||||||
<app-edit [todo]="editingTodo()" />
|
|
||||||
}
|
|
||||||
|
@ -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 {TodoService} from "../service/todo.service";
|
||||||
import {DatePipe} from "@angular/common";
|
import {DatePipe} from "@angular/common";
|
||||||
import {GetTask} from "../dto/models";
|
import {Todo} from "../dto/models";
|
||||||
import EditComponent from "../edit/edit.component";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-table',
|
selector: 'app-table',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
DatePipe,
|
DatePipe,
|
||||||
EditComponent,
|
|
||||||
],
|
],
|
||||||
templateUrl: './table.component.html',
|
templateUrl: './table.component.html',
|
||||||
styleUrl: './table.component.css'
|
styleUrl: './table.component.css'
|
||||||
@ -17,9 +15,9 @@ import EditComponent from "../edit/edit.component";
|
|||||||
export class TableComponent {
|
export class TableComponent {
|
||||||
todoService: TodoService = inject(TodoService);
|
todoService: TodoService = inject(TodoService);
|
||||||
todos = this.todoService.todos;
|
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());
|
this.todoService.toggleDone(todo).subscribe(() => this.todos.reload());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +25,7 @@ export class TableComponent {
|
|||||||
this.todoService.delete(id).subscribe(() => this.todos.reload());
|
this.todoService.delete(id).subscribe(() => this.todos.reload());
|
||||||
}
|
}
|
||||||
|
|
||||||
edit(todo: GetTask) {
|
edit(todo: Todo) {
|
||||||
this.editingTodo.set(todo);
|
this.editingTodo = todo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user