Compare commits
5 Commits
main
...
55f4a665f8
| Author | SHA1 | Date | |
|---|---|---|---|
| 55f4a665f8 | |||
| c09e2655b9 | |||
| d3040c0268 | |||
| ad85a96c33 | |||
| a03322b52d |
@@ -1,59 +1,9 @@
|
|||||||
# DoItEarlier
|
# Do it earlier
|
||||||
|
|
||||||
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 22.0.4.
|
Une application *todo list* destinée à un usage personnel. Ses fonctionnalités sont fortement inspirées par Todoist, dont l'abonnement payant m'a poussé à créer ma propre version.
|
||||||
|
|
||||||
## Development server
|
# Stack
|
||||||
|
|
||||||
To start a local development server, run:
|
Application web réalisée en angular 22.0.4 et node.js 24.18.0.
|
||||||
|
|
||||||
```bash
|
Elle utilise une API maison interrogeant une base de données privée self-hosted.
|
||||||
ng serve
|
|
||||||
```
|
|
||||||
|
|
||||||
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
|
|
||||||
|
|
||||||
## Code scaffolding
|
|
||||||
|
|
||||||
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng generate component component-name
|
|
||||||
```
|
|
||||||
|
|
||||||
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng generate --help
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
To build the project run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng build
|
|
||||||
```
|
|
||||||
|
|
||||||
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
|
|
||||||
|
|
||||||
## Running unit tests
|
|
||||||
|
|
||||||
To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng test
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running end-to-end tests
|
|
||||||
|
|
||||||
For end-to-end (e2e) testing, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ng e2e
|
|
||||||
```
|
|
||||||
|
|
||||||
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
|
||||||
|
|
||||||
## Additional Resources
|
|
||||||
|
|
||||||
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
export interface Group{
|
export interface Group{
|
||||||
id_group: number;
|
id_group: number;
|
||||||
id_project: number;
|
id_project?: number;
|
||||||
name_group: string;
|
name_group: string;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
export interface Task {
|
export interface Task {
|
||||||
date_task: Date;
|
date_task: Date;
|
||||||
id_group: number;
|
id_group?: number;
|
||||||
id_task: number;
|
id_task: number;
|
||||||
name_task: string;
|
name_task: string;
|
||||||
priority_task: number;
|
priority_task: number;
|
||||||
|
|||||||
@@ -5,7 +5,19 @@ import { Observable } from 'rxjs';
|
|||||||
@Service()
|
@Service()
|
||||||
export class BaseService {
|
export class BaseService {
|
||||||
private readonly http: HttpClient = inject(HttpClient);
|
private readonly http: HttpClient = inject(HttpClient);
|
||||||
protected get<T>(url: string):Observable<T> {
|
private readonly baseAddress: string = "http://127.0.0.1:8080/";
|
||||||
return this.http.get<T>(url);
|
|
||||||
|
protected get<T>(url: string): Observable<T> {
|
||||||
|
return this.http.get<T>(this.baseAddress + url);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected post<T>(url: string, body: T): Observable<T> {
|
||||||
|
return this.http.post<T>(this.baseAddress + url, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected delete<T>(url: string): Observable<T> {
|
||||||
|
return this.http.delete<T>(`${this.baseAddress}${url}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,17 @@ import { BaseService } from './base.service';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { Group } from '../model/Group';
|
import { Group } from '../model/Group';
|
||||||
@Service()
|
@Service()
|
||||||
export class GroupService extends BaseService{
|
export class GroupService extends BaseService {
|
||||||
public getGroups():Observable<Group[]>{
|
public getGroups(): Observable<Group[]> {
|
||||||
return this.get<Group[]>("http://127.0.0.1:8080/group");
|
return this.get<Group[]>("group");
|
||||||
|
}
|
||||||
|
|
||||||
|
public addGroup(name:string):Observable<Group>{
|
||||||
|
let body:Group = {
|
||||||
|
id_group:0,
|
||||||
|
name_group:name,
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.post<Group>("group/add",body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,15 @@ import { Project } from '../model/Project';
|
|||||||
@Service()
|
@Service()
|
||||||
export class ProjectService extends BaseService {
|
export class ProjectService extends BaseService {
|
||||||
public getProjects(): Observable<Project[]> {
|
public getProjects(): Observable<Project[]> {
|
||||||
return this.get<Project[]>("http://127.0.0.1:8080/project");
|
return this.get<Project[]>("project");
|
||||||
|
}
|
||||||
|
|
||||||
|
public addProject(name: string): Observable<Project> {
|
||||||
|
let body: Project = {
|
||||||
|
name_project: name,
|
||||||
|
id_project: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.post<Project>("project/add", body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,26 @@ import { Task } from '../model/Task';
|
|||||||
import { BaseService } from './base.service';
|
import { BaseService } from './base.service';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class TaskService extends BaseService{
|
export class TaskService extends BaseService {
|
||||||
public getTasks(): Observable<Task[]> {
|
public getTasks(): Observable<Task[]> {
|
||||||
return this.get<Task[]>("http://127.0.0.1:8080/task");
|
return this.get<Task[]>("task");
|
||||||
|
}
|
||||||
|
|
||||||
|
public addTask(name: string,
|
||||||
|
dueDate: string | null,
|
||||||
|
priority: string | null,
|
||||||
|
status: string | null): Observable<Task> {
|
||||||
|
let body: Task = {
|
||||||
|
name_task: name,
|
||||||
|
date_task: new Date(dueDate!),
|
||||||
|
priority_task: parseInt(priority!),
|
||||||
|
status_task: status!,
|
||||||
|
id_task: 0
|
||||||
|
}
|
||||||
|
return this.post<Task>("task/add", body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteTask(id_task: number): Observable<void> {
|
||||||
|
return this.delete<void>(`task/delete?id=${id_task}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,36 @@
|
|||||||
Section tâches
|
Section tâches
|
||||||
</h2>
|
</h2>
|
||||||
<div>
|
<div>
|
||||||
|
<div>
|
||||||
@for (task of tasks(); track task.id_task) {
|
@for (task of tasks(); track task.id_task) {
|
||||||
<p>
|
<p>
|
||||||
{{ task.name_task }}
|
{{ task.name_task }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<button (click)="deleteTask(task.id_task)">Supprimer la tâche </button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<button (click)="toggleTaskForm()">
|
||||||
|
Ajouter une tâche
|
||||||
|
</button>
|
||||||
|
|
||||||
|
@if (showTaskForm){
|
||||||
|
<form [formGroup]="newTaskForm" (ngSubmit)="submitTask()">
|
||||||
|
<label for="name-task">Nom </label>
|
||||||
|
<input id="name-task" type="text" formControlName="name" />
|
||||||
|
|
||||||
|
<label for="date-task">Date limite </label>
|
||||||
|
<input id="date-task" type="date" formControlName="dueDate" />
|
||||||
|
|
||||||
|
<label for="priority-task">Priorité </label>
|
||||||
|
<input id="priority-task" type="number" formControlName="priority" />
|
||||||
|
|
||||||
|
<label for="status-task">Statut </label>
|
||||||
|
<input id="status-task" type="status" formControlName="status" />
|
||||||
|
|
||||||
|
<button type="submit" [disabled]="!newTaskForm.valid">Valider</button>
|
||||||
|
</form>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -22,6 +48,18 @@
|
|||||||
{{ group.name_group }}
|
{{ group.name_group }}
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<button (click)="toggleGroupForm()">Ajouter un groupe</button>
|
||||||
|
|
||||||
|
|
||||||
|
@if (showGroupForm){
|
||||||
|
<form [formGroup]="newGroupForm" (ngSubmit)="submitGroup()">
|
||||||
|
<label for="name-group">Nom </label>
|
||||||
|
<input id="name-group" type="text" formControlName="name" />
|
||||||
|
|
||||||
|
<button type="submit" [disabled]="!newGroupForm.valid">Valider</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
@@ -33,6 +71,17 @@
|
|||||||
{{ project.name_project }}
|
{{ project.name_project }}
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<button (click)="toggleProjectForm()">Ajouter un projet</button>
|
||||||
|
|
||||||
|
@if (showProjectForm){
|
||||||
|
<form [formGroup]="newProjectForm" (ngSubmit)="submitProject()">
|
||||||
|
<label for="name-project">Nom </label>
|
||||||
|
<input id="name-project" type="text" formControlName="name" />
|
||||||
|
|
||||||
|
<button type="submit" [disabled]="!newProjectForm.valid">Valider</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<router-outlet />
|
<router-outlet />
|
||||||
|
|||||||
@@ -6,14 +6,17 @@ import { GroupService } from '../../../services/group.service';
|
|||||||
import { Group } from '../../../model/Group';
|
import { Group } from '../../../model/Group';
|
||||||
import { ProjectService } from '../../../services/project.service';
|
import { ProjectService } from '../../../services/project.service';
|
||||||
import { Project } from '../../../model/Project';
|
import { Project } from '../../../model/Project';
|
||||||
|
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
imports: [RouterOutlet],
|
imports: [RouterOutlet, ReactiveFormsModule],
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
styleUrl: './home.component.css',
|
styleUrl: './home.component.css',
|
||||||
templateUrl: './home.component.html',
|
templateUrl: './home.component.html',
|
||||||
})
|
})
|
||||||
export class Home {
|
export class Home {
|
||||||
|
//#region Attributs
|
||||||
private taskService: TaskService = inject(TaskService);
|
private taskService: TaskService = inject(TaskService);
|
||||||
private groupService: GroupService = inject(GroupService);
|
private groupService: GroupService = inject(GroupService);
|
||||||
private projectService: ProjectService = inject(ProjectService);
|
private projectService: ProjectService = inject(ProjectService);
|
||||||
@@ -22,17 +25,142 @@ export class Home {
|
|||||||
groups: WritableSignal<Group[]> = signal<Group[]>([]);
|
groups: WritableSignal<Group[]> = signal<Group[]>([]);
|
||||||
projects: WritableSignal<Project[]> = signal<Project[]>([]);
|
projects: WritableSignal<Project[]> = signal<Project[]>([]);
|
||||||
|
|
||||||
|
newTaskForm = new FormGroup({
|
||||||
|
name: new FormControl('', Validators.required),
|
||||||
|
dueDate: new FormControl(''),
|
||||||
|
priority: new FormControl(''),
|
||||||
|
status: new FormControl(''),
|
||||||
|
});
|
||||||
|
|
||||||
|
showTaskForm: boolean = false;
|
||||||
|
|
||||||
|
newGroupForm = new FormGroup({
|
||||||
|
name: new FormControl('', Validators.required),
|
||||||
|
});
|
||||||
|
|
||||||
|
showGroupForm: boolean = false;
|
||||||
|
|
||||||
|
newProjectForm = new FormGroup({
|
||||||
|
name: new FormControl('', Validators.required),
|
||||||
|
});
|
||||||
|
|
||||||
|
showProjectForm: boolean = false;
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.taskService.getTasks().subscribe((response: Task[]): void => {
|
this.taskService.getTasks().subscribe({
|
||||||
|
next: (response: Task[]) => {
|
||||||
this.tasks.set(response);
|
this.tasks.set(response);
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error(`Récupération des tâches impossible\nErreur:${error.error.message}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.groupService.getGroups().subscribe((response: Group[]): void => {
|
this.groupService.getGroups().subscribe({
|
||||||
|
next: (response: Group[]) => {
|
||||||
this.groups.set(response);
|
this.groups.set(response);
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error(`Récupération des groupes impossible\nErreur:${error.error.message}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.projectService.getProjects().subscribe((response: Project[]): void => {
|
this.projectService.getProjects().subscribe({
|
||||||
|
next: (response: Project[]) => {
|
||||||
this.projects.set(response);
|
this.projects.set(response);
|
||||||
})
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error(`Récupération des projets impossible\nErreur:${error.error.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleTaskForm(): void {
|
||||||
|
this.showTaskForm = !this.showTaskForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* submitTask
|
||||||
|
*/
|
||||||
|
public submitTask(): void {
|
||||||
|
let response: Observable<Task> = this.taskService.addTask(this.newTaskForm.controls.name.value!,
|
||||||
|
this.newTaskForm.controls.dueDate.value,
|
||||||
|
this.newTaskForm.controls.priority.value,
|
||||||
|
this.newTaskForm.controls.status.value);
|
||||||
|
|
||||||
|
response.subscribe({
|
||||||
|
next: (response) => {
|
||||||
|
this.tasks.update(values => {
|
||||||
|
return [...values, response];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error(`L'ajout de tâche est impossible\nErreur:${error.error.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deleteTask
|
||||||
|
*/
|
||||||
|
public deleteTask(id_task: number) {
|
||||||
|
let response: Observable<void> = this.taskService.deleteTask(id_task);
|
||||||
|
|
||||||
|
response.subscribe({
|
||||||
|
next: () => {
|
||||||
|
this.tasks.update((tasks) => {
|
||||||
|
return tasks.filter(((task) => task.id_task != id_task));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error(`La suppression de tâche est impossible\nErreur:${error.error.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleGroupForm(): void {
|
||||||
|
this.showGroupForm = !this.showGroupForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* submitGroup
|
||||||
|
*/
|
||||||
|
public submitGroup() {
|
||||||
|
let response: Observable<Group> = this.groupService.addGroup(this.newGroupForm.controls.name.value!);
|
||||||
|
|
||||||
|
response.subscribe({
|
||||||
|
next: (response) => {
|
||||||
|
this.groups.update(values => {
|
||||||
|
return [...values, response];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error(`L'ajout d'un groupe est impossible\nErreur:${error.error.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleProjectForm(): void {
|
||||||
|
this.showProjectForm = !this.showProjectForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* submitProject
|
||||||
|
*/
|
||||||
|
public submitProject() {
|
||||||
|
let response: Observable<Project> = this.projectService.addProject(this.newProjectForm.controls.name.value!);
|
||||||
|
|
||||||
|
response.subscribe({
|
||||||
|
next: (response) => {
|
||||||
|
this.projects.update(values => {
|
||||||
|
return [...values, response];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error(`L'ajout d'un projet est impossible\nErreur:${error.error.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user