From 4a692454413105c378ce30a1ed42ab1ab3d4d03c Mon Sep 17 00:00:00 2001 From: Abigail Cabascango Date: Mon, 31 Oct 2022 14:41:50 -0500 Subject: [PATCH 1/7] fix: TTA-206 implement functions tu validate a running activity in clockin function --- .../project-list-hover.component.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index 66207c63d..224f8264f 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -8,17 +8,19 @@ import { Project } from 'src/app/modules/shared/models'; import * as actions from '../../../customer-management/components/projects/components/store/project.actions'; import { ProjectState } from '../../../customer-management/components/projects/components/store/project.reducer'; import * as entryActions from '../../store/entry.actions'; + import { getIsLoading, getProjects, getRecentProjects, } from './../../../customer-management/components/projects/components/store/project.selectors'; import { EntryActionTypes } from './../../store/entry.actions'; -import { getActiveTimeEntry } from './../../store/entry.selectors'; +import { getActiveTimeEntry, getTimeEntriesDataSource } from './../../store/entry.selectors'; import { Activity, } from '../../../shared/models'; import { LoadActivities } from './../../../activities-management/store/activity-management.actions'; import { allActivities } from 'src/app/modules/activities-management/store/activity-management.selectors'; import { head } from 'lodash'; +import { Entry } from '../../../shared/models'; @Component({ selector: 'app-project-list-hover', @@ -39,6 +41,7 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { recentProjectsSubscription: Subscription; activeEntrySubscription: Subscription; loadActivitiesSubscription: Subscription; + canMarkEntryAsWIP = true; constructor( private formBuilder: FormBuilder, @@ -113,6 +116,9 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { technologies: [], activity_id: head(this.activities).id, }; + this.store.pipe(select(getTimeEntriesDataSource)).subscribe(ds => { + this.canMarkEntryAsWIP = !this.isThereAnEntryRunning(ds.data); + }); this.store.dispatch(new entryActions.ClockIn(entry)); this.projectsForm.setValue({ project_id: `${customerName} - ${name}` }); setTimeout(() => { @@ -120,6 +126,14 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { }, 2000); } + getEntryRunning(entries: Entry[]) { + const runningEntry: Entry = entries.find(entry => entry.running === true); + return runningEntry; + } + isThereAnEntryRunning(entries: Entry[]) { + return !!this.getEntryRunning(entries); + } + updateProject(selectedProject) { const entry = { id: this.activeEntry.id, project_id: selectedProject }; this.store.dispatch(new entryActions.UpdateEntryRunning(entry)); From 9783d05281e5af42ce9df8a9af2bdfe05e6b3616 Mon Sep 17 00:00:00 2001 From: Abigail Cabascango Date: Tue, 1 Nov 2022 09:34:54 -0500 Subject: [PATCH 2/7] FIX: TTA-206 validate if there is a time entry running --- .../project-list-hover.component.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index 224f8264f..3593d9d32 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -119,11 +119,13 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { this.store.pipe(select(getTimeEntriesDataSource)).subscribe(ds => { this.canMarkEntryAsWIP = !this.isThereAnEntryRunning(ds.data); }); - this.store.dispatch(new entryActions.ClockIn(entry)); - this.projectsForm.setValue({ project_id: `${customerName} - ${name}` }); - setTimeout(() => { - this.store.dispatch(new actions.LoadRecentProjects()); - }, 2000); + if ( this.canMarkEntryAsWIP){ + this.store.dispatch(new entryActions.ClockIn(entry)); + this.projectsForm.setValue({ project_id: `${customerName} - ${name}` }); + setTimeout(() => { + this.store.dispatch(new actions.LoadRecentProjects()); + }, 2000); + } } getEntryRunning(entries: Entry[]) { From e25af33f06d04a1afc6dd9afbc291b15cf767138 Mon Sep 17 00:00:00 2001 From: Abigail Cabascango Date: Wed, 2 Nov 2022 11:11:24 -0500 Subject: [PATCH 3/7] test: TTA-206 implement test for validate time entry running in clockin function --- .../project-list-hover.component.spec.ts | 32 +++++++++++++++++++ .../project-list-hover.component.ts | 14 ++++---- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts index 1e553352f..8d6a757d1 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts @@ -83,6 +83,38 @@ describe('ProjectListHoverComponent', () => { expect(store.dispatch).toHaveBeenCalledWith(jasmine.any(ClockIn)); }); + it('when the user make a clockin and there is an existing time entry running the user have an alert', () => { + component.activeEntry = null; + const activitiesMock = [{ + id: 'xyz', + name: 'test', + description : 'test1' + }]; + component.activities = activitiesMock; + spyOn(store, 'dispatch'); + + component.clockIn(1, 'customer', 'project'); + + expect(store.dispatch).toHaveBeenCalledWith(jasmine.any(ClockIn)); + expect(component.canMarkEntryAsWIP).toBe(true); + }); + + it('when the user make a clockin and there is not an existing time entry running the user can make a clokin', () => { + component.activeEntry = null; + const activitiesMock = [{ + id: 'xyz', + name: 'test', + description : 'test1' + }]; + component.activities = activitiesMock; + spyOn(store, 'dispatch'); + + component.clockIn(1, 'customer', 'project'); + + expect(store.dispatch).toHaveBeenCalledWith(jasmine.any(ClockIn)); + expect(component.canMarkEntryAsWIP).toBe(false); + }); + it('dispatch a UpdateEntryRunning action on updateProject', () => { component.activeEntry = { id: '123' }; spyOn(store, 'dispatch'); diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index 3593d9d32..0f37da3bc 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -119,13 +119,15 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { this.store.pipe(select(getTimeEntriesDataSource)).subscribe(ds => { this.canMarkEntryAsWIP = !this.isThereAnEntryRunning(ds.data); }); - if ( this.canMarkEntryAsWIP){ - this.store.dispatch(new entryActions.ClockIn(entry)); - this.projectsForm.setValue({ project_id: `${customerName} - ${name}` }); - setTimeout(() => { - this.store.dispatch(new actions.LoadRecentProjects()); - }, 2000); + if (this.canMarkEntryAsWIP !== false ){ + this.toastrService.error('There is an existing time entry running please check your time entries') + return; } + this.store.dispatch(new entryActions.ClockIn(entry)); + this.projectsForm.setValue({ project_id: `${customerName} - ${name}` }); + setTimeout(() => { + this.store.dispatch(new actions.LoadRecentProjects()); + }, 2000); } getEntryRunning(entries: Entry[]) { From 472b09db6e9dc30fcc799e0e23c8e5da6a7a3e1e Mon Sep 17 00:00:00 2001 From: Abigail Cabascango Date: Wed, 9 Nov 2022 09:57:19 -0500 Subject: [PATCH 4/7] fix: TTA-206 validate clockin --- .../project-list-hover.component.spec.ts | 21 ------------------- .../project-list-hover.component.ts | 16 +++++++++----- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts index 8d6a757d1..a29959557 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts @@ -206,25 +206,4 @@ describe('ProjectListHoverComponent', () => { expect(component.clockIn).toHaveBeenCalledWith(id, customer, name); }); - // TODO Fix this test since it is throwing this error - // Expected spy dispatch to have been called with: - // [CreateEntry({ payload: Object({ project_id: '1', start_date: '2020-07-27T22:30:26.743Z', timezone_offset: 300 }), - // type: '[Entry] CREATE_ENTRY' })] - // but actual calls were: - // [CreateEntry({ payload: Object({ project_id: '1', start_date: '2020-07-27T22:30:26.742Z', timezone_offset: 300 }), - // type: '[Entry] CREATE_ENTRY' })]. - - // Call 0: - // Expected $[0].payload.start_date = '2020-07-27T22:30:26.742Z' to equal '2020-07-27T22:30:26.743Z'. - // it('creates time-entry with timezone_offset property', () => { - // spyOn(store, 'dispatch'); - // component.clockIn('1', 'customer', 'project'); - // expect(store.dispatch).toHaveBeenCalledWith( - // new CreateEntry({ - // project_id: '1', - // start_date: new Date().toISOString(), - // timezone_offset: new Date().getTimezoneOffset() - // }) - // ); - // }); }); diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index 0f37da3bc..723682df1 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -21,6 +21,7 @@ import { LoadActivities } from './../../../activities-management/store/activity- import { allActivities } from 'src/app/modules/activities-management/store/activity-management.selectors'; import { head } from 'lodash'; import { Entry } from '../../../shared/models'; +import { EntryState } from '../../store/entry.reducer'; @Component({ selector: 'app-project-list-hover', @@ -41,10 +42,11 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { recentProjectsSubscription: Subscription; activeEntrySubscription: Subscription; loadActivitiesSubscription: Subscription; - canMarkEntryAsWIP = true; + canMarkEntryAsWIP : boolean; constructor( private formBuilder: FormBuilder, + private storeEntry: Store, private store: Store, private actionsSubject$: ActionsSubject, private toastrService: ToastrService @@ -116,11 +118,13 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { technologies: [], activity_id: head(this.activities).id, }; - this.store.pipe(select(getTimeEntriesDataSource)).subscribe(ds => { - this.canMarkEntryAsWIP = !this.isThereAnEntryRunning(ds.data); + this.canMarkEntryAsWIP = true; + this.storeEntry.pipe(select(getTimeEntriesDataSource)).subscribe(ds => { + this.canMarkEntryAsWIP = this.isThereAnEntryRunning(ds.data); }); - if (this.canMarkEntryAsWIP !== false ){ - this.toastrService.error('There is an existing time entry running please check your time entries') + + if (this.canMarkEntryAsWIP === true ){ + this.toastrService.error('There is an existing time entry running please check your time entries'); return; } this.store.dispatch(new entryActions.ClockIn(entry)); @@ -134,7 +138,9 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { const runningEntry: Entry = entries.find(entry => entry.running === true); return runningEntry; } + isThereAnEntryRunning(entries: Entry[]) { + console.log(!!this.getEntryRunning(entries)) return !!this.getEntryRunning(entries); } From 631f4a4d88610d61e0861e7c2f8137dac7ef4b92 Mon Sep 17 00:00:00 2001 From: Abigail Cabascango Date: Wed, 9 Nov 2022 10:42:35 -0500 Subject: [PATCH 5/7] refactor: refactor tests for TT-206 and fix linters --- .../project-list-hover/project-list-hover.component.spec.ts | 1 + .../project-list-hover/project-list-hover.component.ts | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts index a29959557..bfae8da90 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.spec.ts @@ -94,6 +94,7 @@ describe('ProjectListHoverComponent', () => { spyOn(store, 'dispatch'); component.clockIn(1, 'customer', 'project'); + component.clockIn(2, 'customer', 'project'); expect(store.dispatch).toHaveBeenCalledWith(jasmine.any(ClockIn)); expect(component.canMarkEntryAsWIP).toBe(true); diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index 723682df1..bb030b9d5 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -42,7 +42,7 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { recentProjectsSubscription: Subscription; activeEntrySubscription: Subscription; loadActivitiesSubscription: Subscription; - canMarkEntryAsWIP : boolean; + canMarkEntryAsWIP: boolean; constructor( private formBuilder: FormBuilder, @@ -140,7 +140,6 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { } isThereAnEntryRunning(entries: Entry[]) { - console.log(!!this.getEntryRunning(entries)) return !!this.getEntryRunning(entries); } From 0d39c98f7729ee89f13288530e465649c872252f Mon Sep 17 00:00:00 2001 From: Abigail Cabascango Date: Wed, 9 Nov 2022 11:55:03 -0500 Subject: [PATCH 6/7] fix: TTA-206 solve comment of CR --- .../project-list-hover/project-list-hover.component.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index bb030b9d5..d77df8132 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -123,7 +123,7 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { this.canMarkEntryAsWIP = this.isThereAnEntryRunning(ds.data); }); - if (this.canMarkEntryAsWIP === true ){ + if (this.canMarkEntryAsWIP){ this.toastrService.error('There is an existing time entry running please check your time entries'); return; } @@ -134,16 +134,16 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { }, 2000); } - getEntryRunning(entries: Entry[]) { + private getEntryRunning(entries: Entry[]) { const runningEntry: Entry = entries.find(entry => entry.running === true); return runningEntry; } - isThereAnEntryRunning(entries: Entry[]) { + private isThereAnEntryRunning(entries: Entry[]) { return !!this.getEntryRunning(entries); } - updateProject(selectedProject) { + private updateProject(selectedProject) { const entry = { id: this.activeEntry.id, project_id: selectedProject }; this.store.dispatch(new entryActions.UpdateEntryRunning(entry)); this.store.dispatch(new entryActions.LoadActiveEntry()); From 2f2cff2937109d13ec42eadb29e0bd0257f6be3c Mon Sep 17 00:00:00 2001 From: Abigail Cabascango Date: Fri, 11 Nov 2022 11:53:08 -0500 Subject: [PATCH 7/7] fix: TTA-206 clock in succesfull after clock out --- .../project-list-hover.component.ts | 16 ++++------------ src/app/modules/time-clock/utils/utils.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 src/app/modules/time-clock/utils/utils.ts diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index d77df8132..83e0bf6ef 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -3,6 +3,7 @@ import { FormBuilder, FormGroup } from '@angular/forms'; import { ActionsSubject, select, Store } from '@ngrx/store'; import { ToastrService } from 'ngx-toastr'; import { Observable, Subscription } from 'rxjs'; +import Utils from '../../../time-clock/utils/utils'; import { delay, filter, map } from 'rxjs/operators'; import { Project } from 'src/app/modules/shared/models'; import * as actions from '../../../customer-management/components/projects/components/store/project.actions'; @@ -118,9 +119,9 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { technologies: [], activity_id: head(this.activities).id, }; - this.canMarkEntryAsWIP = true; + this.canMarkEntryAsWIP = false; this.storeEntry.pipe(select(getTimeEntriesDataSource)).subscribe(ds => { - this.canMarkEntryAsWIP = this.isThereAnEntryRunning(ds.data); + this.canMarkEntryAsWIP = Utils.isThereAnEntryRunning(ds.data); }); if (this.canMarkEntryAsWIP){ @@ -134,16 +135,7 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { }, 2000); } - private getEntryRunning(entries: Entry[]) { - const runningEntry: Entry = entries.find(entry => entry.running === true); - return runningEntry; - } - - private isThereAnEntryRunning(entries: Entry[]) { - return !!this.getEntryRunning(entries); - } - - private updateProject(selectedProject) { + updateProject(selectedProject) { const entry = { id: this.activeEntry.id, project_id: selectedProject }; this.store.dispatch(new entryActions.UpdateEntryRunning(entry)); this.store.dispatch(new entryActions.LoadActiveEntry()); diff --git a/src/app/modules/time-clock/utils/utils.ts b/src/app/modules/time-clock/utils/utils.ts new file mode 100644 index 000000000..fb563d3af --- /dev/null +++ b/src/app/modules/time-clock/utils/utils.ts @@ -0,0 +1,12 @@ +import { Entry } from '../../shared/models'; + +export default class Utils { + getEntryRunning(entries: Entry[]) { + const runningEntry: Entry = entries.find(entry => entry.running === true); + return runningEntry; + } + + isThereAnEntryRunning(entries: Entry[]) { + return !!this.getEntryRunning(entries); + } +}