diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 2698e89..69bf2e9 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -3,9 +3,11 @@ import {provideRouter, withComponentInputBinding} from '@angular/router'; import {routes} from './app.routes'; import {MAT_DATE_FORMATS, MAT_NATIVE_DATE_FORMATS, provideNativeDateAdapter} from "@angular/material/core"; +import {provideHttpClient, withFetch, withJsonpSupport} from "@angular/common/http"; export const appConfig: ApplicationConfig = { providers: [ + provideHttpClient(withFetch(), withJsonpSupport()), provideBrowserGlobalErrorListeners(), provideZoneChangeDetection({eventCoalescing: true}), provideRouter(routes, withComponentInputBinding()), diff --git a/src/app/components/add-task/add-task.html b/src/app/components/add-task/add-task.html index 6a8c80b..b9ffb47 100644 --- a/src/app/components/add-task/add-task.html +++ b/src/app/components/add-task/add-task.html @@ -12,43 +12,13 @@

Añadir Tarea

} -
- - Description: - - - - @if(formControls.description?.invalid && (formControls.description?.dirty || formControls.description?.touched || form.submitted)) { - - {{ checkForErrorsIn(formControls.description) | titlecase }} - - } - -
- - Expiration Date: - - - - - - @if(formControls.expirationDate?.invalid && (formControls.expirationDate?.dirty || formControls.expirationDate?.touched || form.submitted)) { - - {{ checkForErrorsIn(formControls.expirationDate) | titlecase }} - - } - -
+
- Priority: + Completed: - - @for (priority of priorities; track priority) { - {{ priority }} + + @for (completedOption of completedOptions; track completedOption) { + {{ completedOption }} } @@ -58,38 +28,6 @@

Añadir Tarea

}
-
- - Status: - - - @for (status of statuses; track status) { - {{ status }} - } - - - @if(formControls.status?.invalid && (formControls.status?.dirty || formControls.status?.touched || form.submitted)) { - - {{ checkForErrorsIn(formControls.status) | titlecase }} - - } - -
- - Category: - - - @for (category of categories; track category) { - {{ category }} - } - - - @if(formControls.category?.invalid && (formControls.category?.dirty || formControls.category?.touched || form.submitted)) { - - {{ checkForErrorsIn(formControls.category) | titlecase }} - - } -
- Statuses - + Status + None - @for (status of statuses; track status) { - {{ status }} - } - - - - Categories - - None - @for (category of categories; track category) { - {{ category }} - } - - - - Priorities - - None - @for (priority of priorities; track priority) { - {{ priority }} + @for (completedOption of completedOptions; track completedOption) { + {{ completedOption }} } + -
- @if (tasks.length === 0) { -

No tasks available.

- } @else { - @for (task of filteredTasks; track task.id) { -
-

{{ task.title }}

-

{{ task.description }}

-

{{ task.expirationDate | date:'dd/MM/yyyy' }}

-

- -

-

- -

-
- } +
+ @if (tasks.length === 0) { +

No tasks available.

+ } @else { + @for (task of filteredTasks; track task.id) { +
+

{{ task.title }}

+

+ +

+

+ +

+
} -
+ }
\ No newline at end of file diff --git a/src/app/components/tasks-list/tasks-list.ts b/src/app/components/tasks-list/tasks-list.ts index 1872e9f..abac2a7 100644 --- a/src/app/components/tasks-list/tasks-list.ts +++ b/src/app/components/tasks-list/tasks-list.ts @@ -1,8 +1,7 @@ import {Component, inject, OnInit} from '@angular/core'; import {TaskService} from '../../services/task-service'; -import {DatePipe} from '@angular/common'; -import {PriorityColor} from "../../shared/directives/priority-color"; -import {Task, TaskCategory, TaskPriority, TaskStatus} from "../../models/task"; +import {CompletionColor} from "../../shared/directives/completion-color.directive"; +import {Task, TaskCompletion,} from "../../models/task"; import {MatIcon} from "@angular/material/icon"; import {MatFabButton} from "@angular/material/button"; import {Router} from "@angular/router"; @@ -15,8 +14,7 @@ import {MatOption, MatSelect} from "@angular/material/select"; @Component({ selector: 'app-tasks-list', imports: [ - DatePipe, - PriorityColor, + CompletionColor, MatIcon, MatFabButton, MatLabel, @@ -33,25 +31,19 @@ export class TasksList implements OnInit { private readonly taskService: TaskService = inject(TaskService) tasks: Task[] = []; + completedOptions = Object.values(TaskCompletion); private readonly dialog: MatDialog; - selectedStatus: TaskStatus | undefined = undefined; - selectedCategory: TaskCategory | undefined = undefined; - selectedPriority: TaskPriority | undefined = undefined; - - priorities = Object.values(TaskPriority); - statuses = Object.values(TaskStatus); - categories = Object.values(TaskCategory); + selectedCompleted: TaskCompletion | undefined = undefined; constructor(dialog: MatDialog) { this.dialog = dialog; } ngOnInit(): void { - this.tasks = this.taskService.getTasks(); + this.taskService.getTasks().subscribe(tasks => this.tasks = tasks); } onModifyTask(task: Task) { - console.log(`The size is ${task.description}.`); this.router.navigate(['/tasks', task.id]).then(); } @@ -63,7 +55,6 @@ export class TasksList implements OnInit { onDeleteTask(task: Task) { console.log(`Delete task with id ${task.id}.`); this.taskService.deleteTask(task.id); - this.tasks = this.taskService.getTasks(); } openDialog(task: Task) { @@ -82,10 +73,6 @@ export class TasksList implements OnInit { } get filteredTasks() { - return this.tasks.filter(task => - (!this.selectedStatus || task.status === this.selectedStatus) && - (!this.selectedCategory || task.category === this.selectedCategory) && - (!this.selectedPriority || task.priority === this.selectedPriority) - ); + return this.tasks.filter(task => !this.selectedCompleted || task.completed === this.selectedCompleted); } } diff --git a/src/app/models/task.ts b/src/app/models/task.ts index 2ed5de2..289bbfe 100644 --- a/src/app/models/task.ts +++ b/src/app/models/task.ts @@ -1,27 +1,12 @@ export interface Task { id: number; + userId: number; title: string; - description: string; - expirationDate: Date; - priority: TaskPriority; - status: TaskStatus; - category: TaskCategory; + completed: TaskCompletion; } -export enum TaskPriority { - Low = "Low", - Medium = "Medium", - High = "High" -} - -export enum TaskStatus { - Pending = "Pending", - InProgress = "In Progress", - Completed = "Completed" -} - -export enum TaskCategory { - Work = "Work", - Personal = "Personal", - Other = "Other" -} +export enum TaskCompletion { + Undefined = "Undefined", + Completed = "Completed", + Pending = "Pending" +} \ No newline at end of file diff --git a/src/app/services/task-service.ts b/src/app/services/task-service.ts index 4781db8..615bf11 100644 --- a/src/app/services/task-service.ts +++ b/src/app/services/task-service.ts @@ -1,46 +1,51 @@ -import {Injectable} from '@angular/core'; -import {Task, TaskCategory, TaskPriority, TaskStatus} from '../models/task'; +import {inject, Injectable} from '@angular/core'; +import {Task, TaskCompletion} from '../models/task'; +import {HttpClient} from "@angular/common/http"; +import {map, Observable} from "rxjs"; @Injectable({ providedIn: 'root' }) export class TaskService { - tasks: Task[] = [ - { - id: 1, title: 'Task 1', description: 'Description for Task 1', category: TaskCategory.Work, - priority: TaskPriority.High, status: TaskStatus.Pending, expirationDate: new Date('2025-12-31') - }, - { - id: 2, title: 'Task 2', description: 'Description for Task 2', category: TaskCategory.Personal, - priority: TaskPriority.Medium, status: TaskStatus.InProgress, expirationDate: new Date('2025-11-30') - }, - { - id: 3, title: 'Task 3', description: 'Description for Task 3', category: TaskCategory.Other, - priority: TaskPriority.Low, status: TaskStatus.Completed, expirationDate: new Date('2025-10-15') - } - ]; + private readonly httpClient = inject(HttpClient); - getTasks(): Task[] { - return this.tasks; + getTasks(): Observable { + return this.httpClient.get('https://jsonplaceholder.typicode.com/todos').pipe( + map(tasks => tasks.map(task => ({ + ...task, + completed: task.completed ? TaskCompletion.Completed : TaskCompletion.Pending + }))) + ); } - getTaskById(id: number): Task | undefined { - return this.tasks.find(task => task.id === id); + getTaskById(id: number): Observable { + return this.httpClient.get(`https://jsonplaceholder.typicode.com/todos/${id}`).pipe( + map(task => ({ + ...task, + completed: task.completed ? TaskCompletion.Completed : TaskCompletion.Pending + })) + ); } - updateTask(id: number, updatedTask: Task): void { - const index = this.tasks.findIndex(task => task.id === id); - if (index !== -1) { - this.tasks[index] = {...updatedTask, id}; // Ensure the ID remains unchanged - } + addTask(newTask: Task): void { + const apiTask = { + ...newTask, + completed: newTask.completed === TaskCompletion.Completed + }; + this.httpClient.post('https://jsonplaceholder.typicode.com/todos', apiTask).subscribe(); } - addTask(newTask: Task): void { - const newId = this.tasks.length > 0 ? Math.max(...this.tasks.map(task => task.id)) + 1 : 1; - this.tasks.push({...newTask, id: newId}); + updateTask(id: number, updatedTask: Task): void { + this.httpClient.put( + `https://jsonplaceholder.typicode.com/todos/${id}`, + { + ...updatedTask, + completed: updatedTask.completed === TaskCompletion.Completed + } + ).subscribe(); } deleteTask(id: number): void { - this.tasks = this.tasks.filter(task => task.id !== id); + this.httpClient.delete(`https://jsonplaceholder.typicode.com/todos/${id}`).subscribe(); } } diff --git a/src/app/shared/directives/completion-color.directive.ts b/src/app/shared/directives/completion-color.directive.ts new file mode 100644 index 0000000..33016e1 --- /dev/null +++ b/src/app/shared/directives/completion-color.directive.ts @@ -0,0 +1,35 @@ +import {Directive, ElementRef, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; +import {TaskCompletion} from "../../models/task"; + +@Directive({ + selector: '[appPriorityColor]' +}) +export class CompletionColor implements OnInit, OnChanges { + @Input("appPriorityColor") completed: TaskCompletion | undefined; + + completionColors: { [key in TaskCompletion]: string } = { + [TaskCompletion.Completed]: '#6ce888', // Green color + [TaskCompletion.Undefined]: '#cfb05e', // Yellow color + [TaskCompletion.Pending]: '#fa596b' // Red color + }; + + constructor(private readonly el: ElementRef) {} + + ngOnInit(): void { + this.updateColor(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.updateColor(); + } + + private updateColor(): void { + console.log(this.completed); + if (this.completed) { + console.log(this.completed); + const color = this.completionColors[this.completed]; + this.el.nativeElement.style.bodeLeft = `4px solid ${color}`; + this.el.nativeElement.style.background = `${color}55`; + } + } +} diff --git a/src/app/shared/directives/priority-color.ts b/src/app/shared/directives/priority-color.ts deleted file mode 100644 index f5caf6f..0000000 --- a/src/app/shared/directives/priority-color.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {Directive, ElementRef, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; -import {TaskPriority} from "../../models/task"; - -@Directive({ - selector: '[appPriorityColor]' -}) -export class PriorityColor implements OnInit, OnChanges { - @Input("appPriorityColor") priority: TaskPriority | undefined; - - priorityColors: { [key in TaskPriority]: string } = { - [TaskPriority.Low]: '#6ce888', // Green color - [TaskPriority.Medium]: '#cfb05e', // Yellow color - [TaskPriority.High]: '#fa596b' // Red color - }; - - constructor(private readonly el: ElementRef) {} - - ngOnInit(): void { - this.updateColor(); - } - - ngOnChanges(changes: SimpleChanges): void { - this.updateColor(); - } - - private updateColor(): void { - console.log(this.priority); - if (this.priority) { - console.log(this.priority); - const color = this.priorityColors[this.priority]; - this.el.nativeElement.style.bodeLeft = `4px solid ${color}`; - this.el.nativeElement.style.background = `${color}55`; - } - } -}