From 3a80c14e0bff240999984f20c808c948cb44ddde Mon Sep 17 00:00:00 2001 From: Diego Tinitana Date: Mon, 15 Jun 2020 10:38:25 -0500 Subject: [PATCH] fix: #371 Add_confirmation_before_deleting_data --- src/app/app.module.ts | 2 + .../activity-list.component.html | 29 ++++- .../activity-list.component.spec.ts | 4 +- .../activity-list/activity-list.component.ts | 16 ++- .../customer-list.component.html | 34 ++++-- .../customer-list.component.spec.ts | 4 +- .../customer-list/customer-list.component.ts | 14 ++- .../project-type-list.component.html | 29 ++++- .../project-type-list.component.spec.ts | 4 +- .../project-type-list.component.ts | 14 ++- .../project-list/project-list.component.html | 21 +++- .../project-list.component.spec.ts | 4 +- .../project-list/project-list.component.ts | 14 ++- .../components/dialog/dialog.component.html | 17 +++ .../components/dialog/dialog.component.scss | 0 .../dialog/dialog.component.spec.ts | 34 ++++++ .../components/dialog/dialog.component.ts | 23 ++++ .../time-clock/store/entry.actions.spec.ts | 1 - .../pages/time-entries.component.html | 102 ++++++++++-------- .../pages/time-entries.component.spec.ts | 3 +- .../pages/time-entries.component.ts | 14 ++- 21 files changed, 300 insertions(+), 83 deletions(-) create mode 100644 src/app/modules/shared/components/dialog/dialog.component.html create mode 100644 src/app/modules/shared/components/dialog/dialog.component.scss create mode 100644 src/app/modules/shared/components/dialog/dialog.component.spec.ts create mode 100644 src/app/modules/shared/components/dialog/dialog.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d15d3cb06..f2af1073a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -66,6 +66,7 @@ import {ReportsComponent} from './modules/reports/pages/reports.component'; import {InputDateComponent} from './modules/shared/components/input-date/input-date.component'; import {TimeRangeFormComponent} from './modules/reports/components/time-range-form/time-range-form.component'; import {TimeEntriesTableComponent} from './modules/reports/components/time-entries-table/time-entries-table.component'; +import { DialogComponent } from './modules/shared/components/dialog/dialog.component'; const maskConfig: Partial = { validation: false, @@ -112,6 +113,7 @@ const maskConfig: Partial = { InputDateComponent, TimeRangeFormComponent, TimeEntriesTableComponent, + DialogComponent, ], imports: [ NgxMaskModule.forRoot(maskConfig), diff --git a/src/app/modules/activities-management/components/activity-list/activity-list.component.html b/src/app/modules/activities-management/components/activity-list/activity-list.component.html index fdbc81cfa..6ba075b27 100644 --- a/src/app/modules/activities-management/components/activity-list/activity-list.component.html +++ b/src/app/modules/activities-management/components/activity-list/activity-list.component.html @@ -10,12 +10,33 @@ {{ activity.name }} - - + + + + diff --git a/src/app/modules/activities-management/components/activity-list/activity-list.component.spec.ts b/src/app/modules/activities-management/components/activity-list/activity-list.component.spec.ts index 5985db7fd..1006dd9e6 100644 --- a/src/app/modules/activities-management/components/activity-list/activity-list.component.spec.ts +++ b/src/app/modules/activities-management/components/activity-list/activity-list.component.spec.ts @@ -50,8 +50,8 @@ describe('ActivityListComponent', () => { it('deleteActivity, dispatchs DeleteActivity action', () => { spyOn(store, 'dispatch'); - - component.deleteActivity('id'); + component.idToDelete = 'id'; + component.deleteActivity(); expect(store.dispatch).toHaveBeenCalledWith(new DeleteActivity('id')); }); diff --git a/src/app/modules/activities-management/components/activity-list/activity-list.component.ts b/src/app/modules/activities-management/components/activity-list/activity-list.component.ts index 02c24bbc9..0138d49f0 100644 --- a/src/app/modules/activities-management/components/activity-list/activity-list.component.ts +++ b/src/app/modules/activities-management/components/activity-list/activity-list.component.ts @@ -14,7 +14,10 @@ import { Activity } from '../../../shared/models'; }) export class ActivityListComponent implements OnInit { activities: Activity[] = []; - + showModal = false; + activityToDelete: Activity; + message: string; + idToDelete: string; constructor(private store: Store) {} ngOnInit() { @@ -26,11 +29,18 @@ export class ActivityListComponent implements OnInit { }); } - deleteActivity(activityId: string) { - this.store.dispatch(new DeleteActivity(activityId)); + deleteActivity() { + this.store.dispatch(new DeleteActivity(this.idToDelete)); + this.showModal = true; } updateActivity(activityId: string) { this.store.dispatch(new SetActivityToEdit(activityId)); } + + openModal(item: Activity) { + this.idToDelete = item.id; + this.message = `Are you sure you want to delete ${item.name}?`; + this.showModal = true; + } } diff --git a/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.html b/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.html index 0f1d093e2..f2ee87eed 100644 --- a/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.html +++ b/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.html @@ -1,4 +1,10 @@ - +
@@ -6,19 +12,35 @@ - +
Name
{{ customer.name }} -
+ + diff --git a/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.spec.ts b/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.spec.ts index 9b453332c..7f073ad7b 100644 --- a/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.spec.ts +++ b/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.spec.ts @@ -67,8 +67,8 @@ describe('CustomerTableListComponent', () => { it('onClick delete, dispatch DeleteCustomer', () => { spyOn(store, 'dispatch'); - - component.deleteCustomer('1'); + component.idToDelete = '1'; + component.deleteCustomer(); expect(store.dispatch).toHaveBeenCalledWith(new DeleteCustomer('1')); }); diff --git a/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.ts b/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.ts index 2b37d232e..da3cc31c3 100644 --- a/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.ts +++ b/src/app/modules/customer-management/components/customer-info/components/customer-list/customer-list.component.ts @@ -29,6 +29,9 @@ export class CustomerListComponent implements OnInit, OnDestroy, AfterViewInit { dtElement: DataTableDirective; loadCustomersSubscription: Subscription; changeCustomerSubscription: Subscription; + showModal = false; + idToDelete: string; + message: string; constructor(private store: Store, private actionsSubject$: ActionsSubject) { } @@ -77,8 +80,9 @@ export class CustomerListComponent implements OnInit, OnDestroy, AfterViewInit { this.store.dispatch(new SetCustomerToEdit(customerId)); } - deleteCustomer(customerId: string) { - this.store.dispatch(new DeleteCustomer(customerId)); + deleteCustomer() { + this.store.dispatch(new DeleteCustomer(this.idToDelete)); + this.showModal = false; } private rerenderDataTable(): void { @@ -91,4 +95,10 @@ export class CustomerListComponent implements OnInit, OnDestroy, AfterViewInit { this.dtTrigger.next(); } } + + openModal(item: Customer) { + this.idToDelete = item.id; + this.message = `Are you sure you want to delete ${item.name}?`; + this.showModal = true; + } } diff --git a/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.html b/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.html index ee29811a6..35f5af4db 100644 --- a/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.html +++ b/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.html @@ -10,12 +10,33 @@ {{ projectType.name }} - - + + + + diff --git a/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.spec.ts b/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.spec.ts index cef9a4438..dcc82f0c3 100644 --- a/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.spec.ts +++ b/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.spec.ts @@ -54,8 +54,8 @@ describe('ProjectTypeTableListComponent', () => { it('dispatchs DeleteProjectType on deleteProjectType', () => { spyOn(store, 'dispatch'); - - component.deleteProjectType('id'); + component.idToDelete = 'id'; + component.deleteProjectType(); expect(store.dispatch).toHaveBeenCalledWith(new DeleteProjectType('id')); }); diff --git a/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.ts b/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.ts index b27a03591..31d8196f1 100644 --- a/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.ts +++ b/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.ts @@ -16,6 +16,9 @@ export class ProjectTypeListComponent implements OnInit { initPage2 = 1; itemsPerPage = ITEMS_PER_PAGE; + showModal = false; + idToDelete: string; + message: string; constructor(private store: Store) {} @@ -26,11 +29,18 @@ export class ProjectTypeListComponent implements OnInit { }); } - deleteProjectType(projectTypeId: string) { - this.store.dispatch(new DeleteProjectType(projectTypeId)); + deleteProjectType() { + this.store.dispatch(new DeleteProjectType(this.idToDelete)); + this.showModal = false; } updateProjectType(projectTypeId: string) { this.store.dispatch(new SetProjectTypeToEdit(projectTypeId)); } + + openModal(item: ProjectType) { + this.idToDelete = item.id; + this.message = `Are you sure you want to delete ${item.name}?`; + this.showModal = true; + } } diff --git a/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.html b/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.html index 8ba4da16e..464c71d2f 100644 --- a/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.html +++ b/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.html @@ -13,7 +13,13 @@ - @@ -21,3 +27,16 @@ + + diff --git a/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.spec.ts b/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.spec.ts index c58432f43..6b719203a 100644 --- a/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.spec.ts +++ b/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.spec.ts @@ -88,10 +88,10 @@ describe('ProjectListComponent', () => { component.projectsSubscription = new Subscription(); const subscription = spyOn(component.projectsSubscription, 'unsubscribe'); + component.idToDelete = project.id; spyOn(store, 'dispatch'); - component.deleteProject(project.id); + component.deleteProject(); component.ngOnDestroy(); - expect(subscription).toHaveBeenCalledTimes(1); expect(store.dispatch).toHaveBeenCalledTimes(1); expect(store.dispatch).toHaveBeenCalledWith(new DeleteProject(project.id)); diff --git a/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.ts b/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.ts index 36c799727..b96e4a61a 100644 --- a/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.ts +++ b/src/app/modules/customer-management/components/projects/components/project-list/project-list.component.ts @@ -18,6 +18,9 @@ export class ProjectListComponent implements OnInit, OnDestroy { isLoading = false; projects: Project[] = []; filterProjects = ''; + showModal = false; + idToDelete: string; + message: string; projectsSubscription: Subscription; @@ -39,7 +42,14 @@ export class ProjectListComponent implements OnInit, OnDestroy { this.store.dispatch(new actions.SetProjectToEdit(project)); } - deleteProject(projectId: string) { - this.store.dispatch(new actions.DeleteProject(projectId)); + deleteProject() { + this.store.dispatch(new actions.DeleteProject(this.idToDelete)); + this.showModal = false; + } + + openModal(item: Project) { + this.idToDelete = item.id; + this.message = `Are you sure you want to delete ${item.name}?`; + this.showModal = true; } } diff --git a/src/app/modules/shared/components/dialog/dialog.component.html b/src/app/modules/shared/components/dialog/dialog.component.html new file mode 100644 index 000000000..1b5f77fd2 --- /dev/null +++ b/src/app/modules/shared/components/dialog/dialog.component.html @@ -0,0 +1,17 @@ + diff --git a/src/app/modules/shared/components/dialog/dialog.component.scss b/src/app/modules/shared/components/dialog/dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/modules/shared/components/dialog/dialog.component.spec.ts b/src/app/modules/shared/components/dialog/dialog.component.spec.ts new file mode 100644 index 000000000..c18602ec5 --- /dev/null +++ b/src/app/modules/shared/components/dialog/dialog.component.spec.ts @@ -0,0 +1,34 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DialogComponent } from './dialog.component'; + +describe('DialogComponent', () => { + let component: DialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should emit removeProject event #removedProject', () => { + spyOn(component.closeModalEvent, 'emit'); + component.body = 'test'; + fixture.detectChanges(); + component.closeModal(); + expect(component.closeModalEvent.emit).toHaveBeenCalled(); + }); + +}); diff --git a/src/app/modules/shared/components/dialog/dialog.component.ts b/src/app/modules/shared/components/dialog/dialog.component.ts new file mode 100644 index 000000000..f250ab335 --- /dev/null +++ b/src/app/modules/shared/components/dialog/dialog.component.ts @@ -0,0 +1,23 @@ +import { Component, OnInit, ViewChild, ElementRef, EventEmitter, Output, Input } from '@angular/core'; + +@Component({ + selector: 'app-dialog', + templateUrl: './dialog.component.html', + styleUrls: ['./dialog.component.scss'], +}) +export class DialogComponent implements OnInit { + @Output() closeModalEvent = new EventEmitter(); + @Input() title: string; + @Input() body: string; + + @ViewChild('cancelDeleteModal') cancelDeleteModal: ElementRef; + + constructor() {} + + ngOnInit(): void {} + + closeModal() { + this.closeModalEvent.emit(); + this.cancelDeleteModal.nativeElement.click(); + } +} diff --git a/src/app/modules/time-clock/store/entry.actions.spec.ts b/src/app/modules/time-clock/store/entry.actions.spec.ts index 9ae626b25..a3c97b438 100644 --- a/src/app/modules/time-clock/store/entry.actions.spec.ts +++ b/src/app/modules/time-clock/store/entry.actions.spec.ts @@ -1,6 +1,5 @@ import * as actions from './entry.actions'; import * as moment from 'moment'; -import { DatePipe } from '@angular/common'; import { TimeEntriesTimeRange } from '../models/time-entries-time-range'; describe('Actions for Entries', () => { diff --git a/src/app/modules/time-entries/pages/time-entries.component.html b/src/app/modules/time-entries/pages/time-entries.component.html index 5e32ed04d..932018fda 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.html +++ b/src/app/modules/time-entries/pages/time-entries.component.html @@ -13,59 +13,54 @@
- -
- - - - - - - - - - - - - - - - - - - - - - - -
DateTime in - outDurationProjectActivity
{{ entry.start_date | date: 'dd/MM/yyyy' }} {{ entry.start_date | date: 'shortTime' }} - {{ entry.end_date | date: 'shortTime' }} {{ entry.end_date | substractDate: entry.start_date }} {{ entry.project_name }} {{ entry.activity_name }} - - -
+ +
+ + + + + + + + + + + + + + + + + + + + + +
DateTime in - outDurationProjectActivity
{{ entry.start_date | date: 'dd/MM/yyyy' }}{{ entry.start_date | date: 'shortTime' }} - {{ entry.end_date | date: 'shortTime' }}{{ entry.end_date | substractDate: entry.start_date }}{{ entry.project_name }}{{ entry.activity_name }} + + +