Add task-list creation.

This commit is contained in:
Florian THIERRY
2022-03-04 10:35:54 +01:00
parent f4d0aa3b27
commit 182cc0bb67
12 changed files with 130 additions and 14 deletions

18
package-lock.json generated
View File

@@ -21,6 +21,7 @@
"ngx-cookie-service": "^12.0.3", "ngx-cookie-service": "^12.0.3",
"rxjs": "~6.6.0", "rxjs": "~6.6.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"uuid": "^8.3.2",
"zone.js": "~0.11.4" "zone.js": "~0.11.4"
}, },
"devDependencies": { "devDependencies": {
@@ -29,6 +30,7 @@
"@angular/compiler-cli": "~12.2.0", "@angular/compiler-cli": "~12.2.0",
"@types/jasmine": "~3.8.0", "@types/jasmine": "~3.8.0",
"@types/node": "^12.11.1", "@types/node": "^12.11.1",
"@types/uuid": "^8.3.4",
"jasmine-core": "~3.8.0", "jasmine-core": "~3.8.0",
"karma": "~6.3.0", "karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0", "karma-chrome-launcher": "~3.1.0",
@@ -2573,6 +2575,12 @@
"integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
"dev": true "dev": true
}, },
"node_modules/@types/uuid": {
"version": "8.3.4",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
"integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==",
"dev": true
},
"node_modules/@types/webpack-sources": { "node_modules/@types/webpack-sources": {
"version": "0.1.9", "version": "0.1.9",
"resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.9.tgz", "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.9.tgz",
@@ -14882,7 +14890,6 @@
"version": "8.3.2", "version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true,
"bin": { "bin": {
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
@@ -17916,6 +17923,12 @@
"integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
"dev": true "dev": true
}, },
"@types/uuid": {
"version": "8.3.4",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
"integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==",
"dev": true
},
"@types/webpack-sources": { "@types/webpack-sources": {
"version": "0.1.9", "version": "0.1.9",
"resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.9.tgz", "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.9.tgz",
@@ -27377,8 +27390,7 @@
"uuid": { "uuid": {
"version": "8.3.2", "version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
"dev": true
}, },
"validate-npm-package-name": { "validate-npm-package-name": {
"version": "3.0.0", "version": "3.0.0",

View File

@@ -23,6 +23,7 @@
"ngx-cookie-service": "^12.0.3", "ngx-cookie-service": "^12.0.3",
"rxjs": "~6.6.0", "rxjs": "~6.6.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"uuid": "^8.3.2",
"zone.js": "~0.11.4" "zone.js": "~0.11.4"
}, },
"devDependencies": { "devDependencies": {
@@ -31,6 +32,7 @@
"@angular/compiler-cli": "~12.2.0", "@angular/compiler-cli": "~12.2.0",
"@types/jasmine": "~3.8.0", "@types/jasmine": "~3.8.0",
"@types/node": "^12.11.1", "@types/node": "^12.11.1",
"@types/uuid": "^8.3.4",
"jasmine-core": "~3.8.0", "jasmine-core": "~3.8.0",
"karma": "~6.3.0", "karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0", "karma-chrome-launcher": "~3.1.0",
@@ -39,4 +41,4 @@
"karma-jasmine-html-reporter": "~1.7.0", "karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.3.5" "typescript": "~4.3.5"
} }
} }

View File

@@ -10,20 +10,32 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {MatIconModule} from '@angular/material/icon'; import {MatIconModule} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input'; import {MatInputModule} from '@angular/material/input';
import { DisplayTaskComponent } from './display-task/display-task.component'; import { DisplayTaskComponent } from './display-task/display-task.component';
import { TaskListsComponent } from './task-lists/task-lists.component';
import { AddTaskListComponent } from './task-lists/add-task-list/add-task-list.component';
import {MatDialogModule} from '@angular/material/dialog';
import {MatButtonModule} from '@angular/material/button';
import {ReactiveFormsModule} from '@angular/forms';
import {MatSnackBarModule} from '@angular/material/snack-bar';
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent, AppComponent,
MainPageComponent, MainPageComponent,
AddTaskComponent, AddTaskComponent,
DisplayTaskComponent DisplayTaskComponent,
TaskListsComponent,
AddTaskListComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
AppRoutingModule, AppRoutingModule,
BrowserAnimationsModule, BrowserAnimationsModule,
MatIconModule, MatIconModule,
MatInputModule MatInputModule,
MatDialogModule,
MatButtonModule,
ReactiveFormsModule,
MatSnackBarModule
], ],
providers: [ providers: [
CookieService, CookieService,

View File

@@ -19,10 +19,17 @@ export class StorePersistenceService {
load(): Store { load(): Store {
const serializedStore = this._cookieService.get(COOKIE_NAME); const serializedStore = this._cookieService.get(COOKIE_NAME);
try {
return JSON.parse(serializedStore); if (serializedStore?.length) {
} catch (jsonParseError) { try {
throw new Error(`JsonSerializationException: Invalid format for store in cookie "${COOKIE_NAME}".`); return JSON.parse(serializedStore);
} catch (jsonParseError) {
throw new Error(`JsonSerializationException: Invalid format for store in cookie "${COOKIE_NAME}".`);
}
} else {
return {
taskLists: []
} as Store;
} }
} }
} }

View File

@@ -3,7 +3,7 @@ import { BehaviorSubject } from "rxjs";
import { Task } from "../entity/task"; import { Task } from "../entity/task";
import { TaskList } from "../entity/task-list"; import { TaskList } from "../entity/task-list";
import { StorePersistenceService } from "./store-persistence.service"; import { StorePersistenceService } from "./store-persistence.service";
import { v4 as uuidv4 } from 'uuid';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -41,7 +41,7 @@ export class TaskListService {
createTaskList(taskListName: string): void { createTaskList(taskListName: string): void {
const newTaskList = { const newTaskList = {
id: taskListName, id: uuidv4(),
name: taskListName, name: taskListName,
tasks: [] tasks: []
} as TaskList; } as TaskList;

View File

@@ -1,8 +1,10 @@
<div class="component"> <div class="component">
<h1>Todo List</h1> <!-- <h1>Todo List</h1>
<app-display-task *ngFor="let task of tasks" [task]="task"></app-display-task> <app-display-task *ngFor="let task of tasks" [task]="task"></app-display-task>
<div id="add-task-btn" *ngIf="!isAddingATask" (click)="createTask()"> <div id="add-task-btn" *ngIf="!isAddingATask" (click)="createTask()">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
<span>Ajouter une nouvelle tâche...</span> <span>Ajouter une nouvelle tâche...</span>
</div> </div> -->
<app-task-lists></app-task-lists>
</div> </div>

View File

@@ -0,0 +1,15 @@
<form [formGroup]="addTaskListFormGroup" (submit)="onSubmit()" ngNativeValidate>
<p>
<mat-form-field>
<mat-label>Nom de la liste</mat-label>
<input matInput autofocus id="task-name-input" name="task-name-input" formControlName="name" />
<mat-error *ngIf="form.name.invalid">
Veuillez saisir le nom de la task-list.
</mat-error>
</mat-form-field>
</p>
<div>
<button mat-raised-button type="button" (click)="close()">Annuler</button>
<button mat-raised-button type="submit">Créer une liste</button>
</div>
</form>

View File

@@ -0,0 +1,42 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialogRef } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { TaskList } from 'src/app/core/entity/task-list';
import { TaskListService } from 'src/app/core/service/task-list.service';
@Component({
selector: 'app-add-task-list',
templateUrl: './add-task-list.component.html',
styleUrls: ['./add-task-list.component.scss']
})
export class AddTaskListComponent {
addTaskListFormGroup: FormGroup = this._formBuilder.group({
name: [undefined, Validators.required]
});
constructor(
private _dialogRef: MatDialogRef<AddTaskListComponent>,
private _formBuilder: FormBuilder,
private _snackBar: MatSnackBar,
private _taskListService: TaskListService
) {}
get form(): any {
return this.addTaskListFormGroup.controls;
}
onSubmit(): void {
if (this.addTaskListFormGroup.valid) {
this._taskListService.createTaskList(this.addTaskListFormGroup.controls.name.value);
this._snackBar.open('La task-list a été créée.', 'Fermer', {duration: 5000});
this.close();
} else {
this._snackBar.open('Veuillez vérifier les informations saisies.', 'Fermer', {duration: 5000});
}
}
close(): void {
this._dialogRef.close();
}
}

View File

@@ -0,0 +1,2 @@
<button mat-raised-button (click)="openNewListForm()">Nouvelle liste</button>

View File

@@ -0,0 +1,22 @@
import { Component, OnInit } from '@angular/core';
import {MatDialog, MatDialogModule} from '@angular/material/dialog';
import { AddTaskListComponent } from './add-task-list/add-task-list.component';
@Component({
selector: 'app-task-lists',
templateUrl: './task-lists.component.html',
styleUrls: ['./task-lists.component.scss']
})
export class TaskListsComponent implements OnInit {
constructor(
private _dialog: MatDialog
) {}
ngOnInit(): void {
}
openNewListForm(): void {
this._dialog.open(AddTaskListComponent);
}
}