Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Expand Down
72 changes: 5 additions & 67 deletions src/app/components/add-task/add-task.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,13 @@ <h2 class="">Añadir Tarea</h2>
</mat-error>
}
</mat-label>
<br/>
<mat-label>
Description:
<mat-form-field>
<textarea matInput
cdkTextareaAutosize
#autosize="cdkTextareaAutosize"
cdkAutosizeMinRows="1"
cdkAutosizeMaxRows="5" formControlName="description"></textarea>
</mat-form-field>
@if(formControls.description?.invalid && (formControls.description?.dirty || formControls.description?.touched || form.submitted)) {
<mat-error>
{{ checkForErrorsIn(formControls.description) | titlecase }}
</mat-error>
}
</mat-label>
<br/>
<mat-label>
Expiration Date:
<mat-form-field>
<input matInput [matDatepicker]="picker" formControlName="expirationDate" >
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
@if(formControls.expirationDate?.invalid && (formControls.expirationDate?.dirty || formControls.expirationDate?.touched || form.submitted)) {
<mat-error>
{{ checkForErrorsIn(formControls.expirationDate) | titlecase }}
</mat-error>
}
</mat-label>
<br/>
<br>
<mat-label>
Priority:
Completed:
<mat-form-field>
<mat-select formControlName="priority">
@for (priority of priorities; track priority) {
<mat-option [value]="priority">{{ priority }}</mat-option>
<mat-select formControlName="completed">
@for (completedOption of completedOptions; track completedOption) {
<mat-option [value]="completedOption">{{ completedOption }}</mat-option>
}
</mat-select>
</mat-form-field>
Expand All @@ -58,38 +28,6 @@ <h2 class="">Añadir Tarea</h2>
</mat-error>
}
</mat-label>
<br/>
<mat-label>
Status:
<mat-form-field>
<mat-select formControlName="status">
@for (status of statuses; track status) {
<mat-option [value]="status">{{ status }}</mat-option>
}
</mat-select>
</mat-form-field>
@if(formControls.status?.invalid && (formControls.status?.dirty || formControls.status?.touched || form.submitted)) {
<mat-error>
{{ checkForErrorsIn(formControls.status) | titlecase }}
</mat-error>
}
</mat-label>
<br/>
<mat-label>
Category:
<mat-form-field>
<mat-select formControlName="category">
@for (category of categories; track category) {
<mat-option [value]="category">{{ category }}</mat-option>
}
</mat-select>
</mat-form-field>
@if(formControls.category?.invalid && (formControls.category?.dirty || formControls.category?.touched || form.submitted)) {
<mat-error>
{{ checkForErrorsIn(formControls.category) | titlecase }}
</mat-error>
}
</mat-label>
<br>
<button matFab extended type="submit" [disabled]="form.pristine">
<mat-icon>save</mat-icon>
Expand Down
32 changes: 11 additions & 21 deletions src/app/components/add-task/add-task.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,40 @@
import {Component, inject} from '@angular/core';
import {AbstractControl, FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
import {CdkTextareaAutosize} from "@angular/cdk/text-field";
import {MatDatepicker, MatDatepickerInput, MatDatepickerToggle} from "@angular/material/datepicker";
import {MatFabButton} from "@angular/material/button";
import {MatIcon} from "@angular/material/icon";
import {MatError, MatFormField, MatInput, MatLabel, MatSuffix} from "@angular/material/input";
import {MatOption, MatSelect} from "@angular/material/select";
import {TaskCategory, TaskPriority, TaskStatus} from "../../models/task";
import {MatError, MatFormField, MatInput, MatLabel} from "@angular/material/input";
import {TaskService} from "../../services/task-service";
import {MatSnackBar} from "@angular/material/snack-bar";
import {TitleCasePipe} from "@angular/common";
import {TaskCompletion} from "../../models/task";
import {MatOption, MatSelect} from "@angular/material/select";

@Component({
selector: 'app-add-task',
imports: [
ReactiveFormsModule,
CdkTextareaAutosize,
MatDatepicker,
MatDatepickerInput,
MatDatepickerToggle,
MatFabButton,
MatFormField,
MatIcon,
MatInput,
MatLabel,
MatOption,
MatSelect,
MatSuffix,
MatError,
TitleCasePipe
TitleCasePipe,
MatOption,
MatSelect
],
templateUrl: './add-task.html',
styleUrl: './add-task.css'
})
export class AddTask {
completedOptions = Object.values(TaskCompletion);
private readonly taskService = inject(TaskService);
protected snackBar = inject(MatSnackBar);
priorities = Object.values(TaskPriority);
statuses = Object.values(TaskStatus);
categories = Object.values(TaskCategory);

taskForm: FormGroup = new FormGroup({
id: new FormControl(0),
title: new FormControl("", [Validators.minLength(3), Validators.required]),
description: new FormControl(""),
expirationDate: new FormControl<Date | null>(null, Validators.required),
priority: new FormControl("", Validators.required),
status: new FormControl("", Validators.required),
category: new FormControl("", Validators.required)
completed: new FormControl(false)
});

get formControls(): any {
Expand All @@ -59,10 +47,12 @@ export class AddTask {
this.taskService.addTask(this.taskForm.value);
this.snackBar.open('Task created successfully!', 'Dismiss', {
panelClass: ['snackbar-success'],
duration: 3000
});
} else {
this.snackBar.open('Please fill in all required fields.', 'OK', {
panelClass: ['snackbar-error'],
duration: 3000
});
}
}
Expand Down
70 changes: 4 additions & 66 deletions src/app/components/task-detail/task-detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,11 @@ <h2 class="">Formulario de Tarea</h2>
</mat-label>
<br/>
<mat-label>
Description:
Completed:
<mat-form-field>
<textarea matInput
cdkTextareaAutosize
#autosize="cdkTextareaAutosize"
cdkAutosizeMinRows="1"
cdkAutosizeMaxRows="5" formControlName="description"></textarea>
</mat-form-field>
@if(formControls.description?.invalid && (formControls.description?.dirty || formControls.description?.touched || form.submitted)) {
<mat-error>
{{ checkForErrorsIn(formControls.description) | titlecase }}
</mat-error>
}
</mat-label>
<br/>
<mat-label>
Expiration Date:
<mat-form-field>
<input matInput [matDatepicker]="picker" formControlName="expirationDate" >
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
@if(formControls.expirationDate?.invalid && (formControls.expirationDate?.dirty || formControls.expirationDate?.touched || form.submitted)) {
<mat-error>
{{ checkForErrorsIn(formControls.expirationDate) | titlecase }}
</mat-error>
}
</mat-label>
<br/>
<mat-label>
Priority:
<mat-form-field>
<mat-select formControlName="priority">
@for (priority of priorities; track priority) {
<mat-option [value]="priority">{{ priority }}</mat-option>
<mat-select formControlName="completed">
@for (completedOption of completedOptions; track completedOption) {
<mat-option [value]="completedOption">{{ completedOption }}</mat-option>
}
</mat-select>
</mat-form-field>
Expand All @@ -59,38 +29,6 @@ <h2 class="">Formulario de Tarea</h2>
</mat-error>
}
</mat-label>
<br/>
<mat-label>
Status:
<mat-form-field>
<mat-select formControlName="status">
@for (status of statuses; track status) {
<mat-option [value]="status">{{ status }}</mat-option>
}
</mat-select>
</mat-form-field>
@if(formControls.status?.invalid && (formControls.status?.dirty || formControls.status?.touched || form.submitted)) {
<mat-error>
{{ checkForErrorsIn(formControls.status) | titlecase }}
</mat-error>
}
</mat-label>
<br/>
<mat-label>
Category:
<mat-form-field>
<mat-select formControlName="category">
@for (category of categories; track category) {
<mat-option [value]="category">{{ category }}</mat-option>
}
</mat-select>
</mat-form-field>
@if(formControls.category?.invalid && (formControls.category?.dirty || formControls.category?.touched || form.submitted)) {
<mat-error>
{{ checkForErrorsIn(formControls.category) | titlecase }}
</mat-error>
}
</mat-label>
<br>
<button matFab extended type="submit" [disabled]="form.pristine">
<mat-icon>save</mat-icon>
Expand Down
62 changes: 23 additions & 39 deletions src/app/components/task-detail/task-detail.ts
Original file line number Diff line number Diff line change
@@ -1,72 +1,57 @@
import {Component, inject, signal} from '@angular/core';
import {AbstractControl, FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
import {Task, TaskCategory, TaskPriority, TaskStatus} from "../../models/task";
import {Task, TaskCompletion} from "../../models/task";
import {MatFabButton} from "@angular/material/button";
import {MatIcon} from "@angular/material/icon";
import {ActivatedRoute} from "@angular/router";
import {TaskService} from "../../services/task-service";
import {MatDatepicker, MatDatepickerInput, MatDatepickerToggle} from "@angular/material/datepicker";
import {MatError, MatFormField, MatInput, MatLabel, MatSuffix} from "@angular/material/input";
import {MatOption, MatSelect} from "@angular/material/select";
import {CdkTextareaAutosize} from "@angular/cdk/text-field";
import {MatError, MatFormField, MatInput, MatLabel} from "@angular/material/input";
import {MatSnackBar} from "@angular/material/snack-bar";
import {TitleCasePipe} from "@angular/common";
import {MatSelect, MatOption} from "@angular/material/select";

@Component({
selector: 'app-task-detail',
imports: [
ReactiveFormsModule,
MatFabButton,
MatIcon,
MatDatepickerInput,
MatDatepicker,
MatInput,
MatDatepickerToggle,
MatSuffix,
MatFormField,
MatSelect,
MatOption,
MatLabel,
CdkTextareaAutosize,
MatError,
TitleCasePipe
TitleCasePipe,
MatSelect,
MatOption
],
templateUrl: './task-detail.html',
styleUrl: './task-detail.css'
})
export class TaskDetail {
priorities = Object.values(TaskPriority);
statuses = Object.values(TaskStatus);
categories = Object.values(TaskCategory);
completedOptions = Object.values(TaskCompletion);
taskForm= new FormGroup({
id: new FormControl(0, Validators.required),
title: new FormControl("", Validators.minLength(3)),
description: new FormControl("", Validators.minLength(5)),
expirationDate: new FormControl<Date>(new Date(), Validators.required),
priority: new FormControl("", Validators.required),
status: new FormControl("", Validators.required),
category: new FormControl("", Validators.required)
completed: new FormControl(TaskCompletion.Undefined)
});
private readonly activatedRoute = inject(ActivatedRoute);
private readonly taskService = inject(TaskService);
taskId = signal('');
private readonly task: Task | undefined;
private task: Task | undefined;
protected snackBar = inject(MatSnackBar);

constructor() {
this.activatedRoute.params.subscribe((params) => { this.taskId.set(params['id']); });
this.task = this.taskService.getTaskById(Number(this.taskId()));
if (this.task) {
this.taskForm.setValue({
id: this.task.id,
title: this.task.title,
description: this.task.description,
expirationDate: new Date(this.task.expirationDate),
priority: this.task.priority,
status: this.task.status,
category: this.task.category
});
}
this.taskService.getTaskById(Number(this.taskId())).subscribe(task => {
this.task = task;
if (this.task) {
this.taskForm.setValue({
id: this.task.id,
title: this.task.title,
completed: this.task.completed
});
}
});
}

get formControls(): any {
Expand All @@ -78,21 +63,20 @@ export class TaskDetail {
console.log("Form Submitted!", this.taskForm.value);
const task : Task = {
id: this.taskForm.value.id!,
userId: this.task?.userId || 0,
title: this.taskForm.value.title!,
description: this.taskForm.value.description!,
expirationDate: new Date(this.taskForm.value.expirationDate!),
priority: this.taskForm.value.priority as TaskPriority,
status: this.taskForm.value.status as TaskStatus,
category: this.taskForm.value.category as TaskCategory
completed: this.taskForm.value.completed!
};
this.taskService.updateTask(Number(this.taskId()), task);
this.snackBar.open('Task updated successfully!', 'Dismiss', {
panelClass: ['snackbar-success'],
duration: 3000
});
}
else {
this.snackBar.open('Please fill in all required fields.', 'OK', {
panelClass: ['snackbar-error'],
duration: 3000
});
}
}
Expand Down
Loading