Skip to content

Commit 7337155

Browse files
committed
New functionality
Created actions for update and delete a project
1 parent 9701bdd commit 7337155

File tree

4 files changed

+278
-9
lines changed

4 files changed

+278
-9
lines changed

task-manager/src/app/projects/components/project-list-item/project-list-item.component.ts

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,66 @@
1-
import { Component, HostBinding, inject, Input } from '@angular/core';
1+
import {
2+
ChangeDetectionStrategy,
3+
ChangeDetectorRef,
4+
Component,
5+
HostBinding,
6+
inject,
7+
Input,
8+
OnDestroy,
9+
} from '@angular/core';
210
import { CommonModule } from '@angular/common';
3-
import { ButtonComponent, Project, StoreProjectService, TagComponent } from 'src/app/shared';
4-
import * as moment from 'moment';
11+
512
import { faClock, faPencilAlt, faTrash } from '@fortawesome/free-solid-svg-icons';
613
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
714

15+
import * as moment from 'moment';
16+
17+
import { of, Subscription, switchMap } from 'rxjs';
18+
19+
import {
20+
ButtonComponent,
21+
DatabaseService,
22+
ModalService,
23+
NotificationService,
24+
Project,
25+
ProjectRepository,
26+
ProjectService,
27+
StoreProjectService,
28+
TagComponent,
29+
} from 'src/app/shared';
30+
31+
import { PROJECT_REPOSITORY_TOKEN } from 'src/app/injection-tokens';
32+
import { UpdateProjectModalComponent } from '../update-project-modal/update-project-modal.component';
33+
834
@Component({
935
standalone: true,
1036
selector: 'tm-project-list-item',
1137
templateUrl: './project-list-item.component.html',
1238
styleUrls: ['./project-list-item.component.css'],
39+
changeDetection: ChangeDetectionStrategy.OnPush,
1340
imports: [CommonModule, TagComponent, ButtonComponent, FontAwesomeModule],
41+
providers: [
42+
ModalService,
43+
DatabaseService,
44+
NotificationService,
45+
NotificationService,
46+
{ provide: PROJECT_REPOSITORY_TOKEN, useClass: ProjectService },
47+
],
1448
})
15-
export class ProjectListItemComponent {
49+
export class ProjectListItemComponent implements OnDestroy {
50+
private readonly modalService: ModalService;
51+
private readonly changeDetectorRef: ChangeDetectorRef;
52+
private readonly projectRepository: ProjectRepository;
1653
private readonly storeProjectService: StoreProjectService;
54+
private readonly notificationService: NotificationService;
55+
56+
private projectRepositoryDelete$!: Subscription;
1757

1858
public constructor() {
59+
this.modalService = inject(ModalService);
60+
this.changeDetectorRef = inject(ChangeDetectorRef);
1961
this.storeProjectService = inject(StoreProjectService);
62+
this.notificationService = inject(NotificationService);
63+
this.projectRepository = inject<ProjectRepository>(PROJECT_REPOSITORY_TOKEN);
2064
}
2165

2266
@Input() public project!: Project;
@@ -56,10 +100,29 @@ export class ProjectListItemComponent {
56100

57101
public onUpdate(event: MouseEvent) {
58102
event.stopImmediatePropagation();
103+
this.modalService.create({
104+
title: 'Update Project',
105+
closeDisabled: true,
106+
submitDisabled: true,
107+
component: UpdateProjectModalComponent,
108+
params: {
109+
project: this.project,
110+
},
111+
});
59112
}
60113

61114
public onDelete(event: MouseEvent) {
115+
this.projectRepositoryDelete$ = this.projectRepository.delete(this.project.id).subscribe({
116+
next: () => {
117+
this.storeProjectService.delete(this.project, 'id');
118+
this.notificationService.success('Project deleted successfully.');
119+
this.changeDetectorRef.detectChanges();
120+
},
121+
});
62122
event.stopImmediatePropagation();
63-
this.storeProjectService.delete(this.project, 'id');
123+
}
124+
125+
public ngOnDestroy(): void {
126+
this.projectRepositoryDelete$?.unsubscribe();
64127
}
65128
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
:host {
2+
display: inline-flex;
3+
width: 100%;
4+
height: 100%;
5+
}
6+
7+
.form {
8+
width: 100%;
9+
height: 100%;
10+
display: inline-flex;
11+
flex-direction: column;
12+
justify-content: center;
13+
align-items: flex-start;
14+
box-sizing: border-box;
15+
gap: 0.5em;
16+
}
17+
18+
.date-section {
19+
padding: 0em;
20+
width: 100%;
21+
display: inline-grid;
22+
grid-template-columns: repeat(2, 1fr);
23+
gap: 1em;
24+
box-sizing: border-box;
25+
}
26+
27+
.form-item {
28+
width: 100%;
29+
margin: 0em;
30+
padding: 0em;
31+
}
Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,65 @@
1-
<p>update-project-model works!</p>
1+
<form class="form" [formGroup]="formService.form">
2+
<tm-input
3+
label="Title"
4+
type="text"
5+
name="title"
6+
class="form-item"
7+
placeholder="Project's title here ..."
8+
[formControlName]="formService.titleFormName">
9+
<span [hidden]="!formService.titleFormControl.hasError('required')" class="error-message">
10+
• Il titolo del progetto è obbligatorio
11+
</span>
12+
<span [hidden]="!formService.titleFormControl.hasError('minlength')" class="error-message">
13+
• Il titolo del progetto deve essere lungo minimo 2 caratteri
14+
</span>
15+
<span [hidden]="!formService.titleFormControl.hasError('maxlength')" class="error-message">
16+
• Il titolo del progetto deve essere lungo massimo 255 caratteri
17+
</span>
18+
</tm-input>
19+
<tm-textarea
20+
label="Description"
21+
type="text"
22+
name="description"
23+
class="form-item"
24+
placeholder="Project's description here ..."
25+
[formControlName]="formService.descriptionFormName">
26+
<span [hidden]="!formService.descriptionFormControl.hasError('required')" class="error-message">
27+
• La descrizione del progetto è obbligatoria
28+
</span>
29+
<span [hidden]="!formService.descriptionFormControl.hasError('minlength')" class="error-message">
30+
• La descrizione del progetto deve essere lunga minimo 2 caratteri
31+
</span>
32+
<span [hidden]="!formService.descriptionFormControl.hasError('maxlength')" class="error-message">
33+
• La descrizione del progetto deve essere lunga massimo 255 caratteri
34+
</span>
35+
</tm-textarea>
36+
<div class="date-section">
37+
<tm-input
38+
label="Starting Date"
39+
type="date"
40+
name="starting-date"
41+
class="form-item"
42+
placeholder="Project's starting date ..."
43+
[formControlName]="formService.startingDateFormName">
44+
<span [hidden]="!formService.startingDateFormControl?.hasError('required')" class="error-message">
45+
• La data di inizio è obbligatoria
46+
</span>
47+
<span
48+
[hidden]="!formService.startingDateFormControl?.hasError('notBeforeToday')"
49+
class="error-message">
50+
• La data di inizio non può precedere oggi
51+
</span>
52+
</tm-input>
53+
<tm-input
54+
label="Ending Date"
55+
type="date"
56+
name="ending-date"
57+
class="form-item"
58+
placeholder="Project's ending date ..."
59+
[formControlName]="formService.endingDateFormName">
60+
<span [hidden]="!formService.endingDateFormControl?.hasError('required')" class="error-message">
61+
• La data di fine è obbligatoria
62+
</span>
63+
</tm-input>
64+
</div>
65+
</form>
Lines changed: 114 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,122 @@
1-
import { Component } from '@angular/core';
1+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnDestroy, OnInit } from '@angular/core';
22
import { CommonModule } from '@angular/common';
3+
import {
4+
DatabaseService,
5+
InputComponent,
6+
LocalStorageService,
7+
ModalComponent,
8+
NotificationService,
9+
Project,
10+
ProjectRepository,
11+
ProjectService,
12+
StoreProjectService,
13+
TextareaComponent,
14+
} from 'src/app/shared';
15+
import { ReactiveFormsModule } from '@angular/forms';
16+
import { ProjectFormService } from '../../services';
17+
import { Subscription, switchMap } from 'rxjs';
18+
import { PROJECT_REPOSITORY_TOKEN } from 'src/app/injection-tokens';
319

420
@Component({
521
standalone: true,
6-
imports: [CommonModule],
722
selector: 'tm-update-project-model',
823
templateUrl: './update-project-modal.component.html',
924
styleUrls: ['./update-project-modal.component.css'],
25+
changeDetection: ChangeDetectionStrategy.OnPush,
26+
providers: [
27+
DatabaseService,
28+
ProjectFormService,
29+
LocalStorageService,
30+
NotificationService,
31+
{ provide: PROJECT_REPOSITORY_TOKEN, useClass: ProjectService },
32+
],
33+
imports: [CommonModule, InputComponent, TextareaComponent, ReactiveFormsModule],
1034
})
11-
export class UpdateProjectModalComponent {}
35+
export class UpdateProjectModalComponent implements OnInit, OnDestroy {
36+
@Input('project') public project!: Project;
37+
@Input('modalInstance') public modalInstance!: ModalComponent;
38+
39+
private title!: string;
40+
private description!: string;
41+
private startingDate!: Date;
42+
private endingDate!: Date;
43+
44+
private okEvent$!: Subscription;
45+
private closeEvent$!: Subscription;
46+
private formChanging$!: Subscription;
47+
48+
private readonly changeDetectorRef: ChangeDetectorRef;
49+
private readonly projectRepository: ProjectRepository;
50+
private readonly projectFormService: ProjectFormService;
51+
private readonly storeProjectService: StoreProjectService;
52+
private readonly notificationService: NotificationService;
53+
private readonly localStorageService: LocalStorageService;
54+
55+
public constructor() {
56+
this.changeDetectorRef = inject(ChangeDetectorRef);
57+
this.projectFormService = inject(ProjectFormService);
58+
this.localStorageService = inject(LocalStorageService);
59+
this.notificationService = inject(NotificationService);
60+
this.storeProjectService = inject(StoreProjectService);
61+
this.projectRepository = inject<ProjectRepository>(PROJECT_REPOSITORY_TOKEN);
62+
}
63+
64+
public ngOnInit(): void {
65+
this.modalInstance.disableSubmit = true;
66+
67+
this.projectFormService.data = {
68+
title: this.project.title,
69+
description: this.project.description,
70+
startingDate: this.project.startingAt,
71+
endingDate: this.project.endingAt,
72+
};
73+
74+
this.formChanging$ = this.projectFormService.subscribeOnValueChanges({
75+
next: (value) => {
76+
const { title, description, starting_date, ending_date } = value;
77+
this.title = title;
78+
this.description = description;
79+
this.startingDate = starting_date;
80+
this.endingDate = ending_date;
81+
this.modalInstance.disableSubmit = !this.projectFormService.form.valid;
82+
this.changeDetectorRef.detectChanges();
83+
},
84+
});
85+
86+
this.okEvent$ = this.modalInstance.okEvent
87+
.pipe(
88+
switchMap(() =>
89+
this.projectRepository.update(this.project.id, {
90+
title: this.title,
91+
description: this.description,
92+
startingAt: this.startingDate,
93+
endingAt: this.endingDate,
94+
ownerId: this.localStorageService.userId,
95+
}),
96+
),
97+
)
98+
.subscribe({
99+
next: (newProject) => {
100+
this.storeProjectService.update(newProject, 'id');
101+
this.notificationService.success('Project updated successfully');
102+
this.changeDetectorRef.detectChanges();
103+
this.ngOnDestroy();
104+
this.modalInstance.onClose();
105+
},
106+
});
107+
108+
this.closeEvent$ = this.modalInstance.closeEvent.subscribe({
109+
next: () => this.ngOnDestroy(),
110+
});
111+
}
112+
113+
public get formService() {
114+
return this.projectFormService;
115+
}
116+
117+
public ngOnDestroy(): void {
118+
this.okEvent$.unsubscribe();
119+
this.closeEvent$.unsubscribe();
120+
this.formChanging$.unsubscribe();
121+
}
122+
}

0 commit comments

Comments
 (0)