Skip to content
Snippets Groups Projects
Commit fb9037bf authored by thibault.capt's avatar thibault.capt
Browse files

(feat): delete a todo

parent ab702d7c
No related branches found
No related tags found
No related merge requests found
import { Component } from '@angular/core';
import {TodoListComponent} from "@features/todo-list/todo-list.component";
import { Component, inject } from '@angular/core';
import { TodoListComponent } from '@features/todo-list/todo-list.component';
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { faIcons } from '@shared/fa-icons';
@Component({
selector: 'app-root',
imports: [
TodoListComponent
],
imports: [TodoListComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
})
export class AppComponent {}
export class AppComponent {
constructor() {
inject(FaIconLibrary).addIcons(...faIcons);
}
}
......@@ -5,6 +5,7 @@ import { routes } from './app.routes';
import { provideHttpClient } from '@angular/common/http';
import { TodoService } from '@core/ports/todo.service';
import { InMemoryTodoService } from '@core/adapters/in-memory-todo.service';
import { TodoBuilder } from '@core/models/builder/todo.builder';
export const appConfig: ApplicationConfig = {
providers: [
......@@ -15,9 +16,9 @@ export const appConfig: ApplicationConfig = {
provide: TodoService,
useFactory: () =>
new InMemoryTodoService().withTodos([
{ id: 1, name: 'Apprendre Angular 19', completed: false },
{ id: 1, name: 'Apprendre Java Spring Boot', completed: true },
{ id: 1, name: 'Apprendre PostgreSQL', completed: false },
new TodoBuilder().withId(1).withName('Apprendre Angular 19').uncomplete().build(),
new TodoBuilder().withId(2).withName('Apprendre Java Spring Boot').complete().build(),
new TodoBuilder().withId(3).withName('Apprendre PostgreSQL').uncomplete().build(),
]),
},
],
......
import { Observable, of } from 'rxjs';
import { TodoService } from '@core/ports/todo.service';
import { Todo, Todos } from '@core/models/todo';
import { TodoBuilder } from '@core/models/builder/todo.builder';
export class InMemoryTodoService extends TodoService {
private todos: Todos = [];
......@@ -15,8 +16,23 @@ export class InMemoryTodoService extends TodoService {
}
override add(todoName: string): Observable<Todo> {
const todo: Todo = { id: this.todos.length + 1, name: todoName, completed: false };
const todo: Todo = new TodoBuilder()
.withId(this.todos.length + 1)
.withName(todoName)
.uncomplete()
.build();
this.todos = [...this.todos, todo];
return of(todo);
}
override toggleCompleted(todoId: number): Observable<Todo> {
const todo = this.todos.find((todo) => todo.id === todoId)!;
todo.completed = !todo.completed;
return of(todo);
}
override remove(todoId: number): Observable<void> {
this.todos = this.todos.filter((todo) => todo.id !== todoId);
return of(void 0);
}
}
import { Todo } from '@core/models/todo';
export class TodoBuilder {
protected id!: number;
protected name!: string;
protected completed!: boolean;
withId(id: number): this {
this.id = id;
return this;
}
withName(name: string): this {
this.name = name;
return this;
}
complete(): this {
this.completed = true;
return this;
}
uncomplete(): this {
this.completed = false;
return this;
}
build(): Todo {
return {
id: this.id,
name: this.name,
completed: this.completed,
};
}
}
......@@ -4,4 +4,6 @@ import { Todo, Todos } from '@core/models/todo';
export abstract class TodoService {
abstract getAll(): Observable<Todos>;
abstract add(todoName: string): Observable<Todo>;
abstract toggleCompleted(todoId: number): Observable<Todo>;
abstract remove(todoId: number): Observable<void>;
}
......@@ -23,8 +23,11 @@
@for (todo of todos(); track todo.id) {
<li class="py-2 w-full">
<label class="fieldset-label">
<input type="checkbox" [checked]="todo.completed" class="checkbox" />
<input type="checkbox" [checked]="todo.completed" class="checkbox" (change)="toggleCompleted(todo)" />
<span [ngClass]="{ 'line-through': todo.completed }">{{ todo.name }}</span>
<button class="btn btn-ghost btn-error" (click)="remove(todo)">
<fa-icon [icon]="['fas', 'trash']"></fa-icon>
</button>
</label>
</li>
}
......
......@@ -4,10 +4,12 @@ import { toSignal } from '@angular/core/rxjs-interop';
import { NgClass } from '@angular/common';
import { BehaviorSubject, switchMap, tap } from 'rxjs';
import { FormsModule } from '@angular/forms';
import { Todo } from '@core/models/todo';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
@Component({
selector: 'app-todo-list',
imports: [NgClass, FormsModule],
imports: [NgClass, FormsModule, FaIconComponent],
templateUrl: './todo-list.component.html',
styleUrl: './todo-list.component.scss',
})
......@@ -28,4 +30,18 @@ export class TodoListComponent {
.pipe(tap(() => this.reload$$.next()))
.subscribe();
}
toggleCompleted(todo: Todo) {
this.todoService
.toggleCompleted(todo.id)
.pipe(tap(() => this.reload$$.next()))
.subscribe();
}
remove(todo: Todo) {
this.todoService
.remove(todo.id)
.pipe(tap(() => this.reload$$.next()))
.subscribe();
}
}
import { IconDefinition } from '@fortawesome/angular-fontawesome';
import { faTrash } from '@fortawesome/free-solid-svg-icons';
export const faIcons: IconDefinition[] = [faTrash];
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment