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..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 @@ -83,6 +83,39 @@ 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'); + component.clockIn(2, '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'); @@ -174,25 +207,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 66207c63d..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,22 +3,26 @@ 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'; 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'; +import { EntryState } from '../../store/entry.reducer'; @Component({ selector: 'app-project-list-hover', @@ -39,9 +43,11 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { recentProjectsSubscription: Subscription; activeEntrySubscription: Subscription; loadActivitiesSubscription: Subscription; + canMarkEntryAsWIP: boolean; constructor( private formBuilder: FormBuilder, + private storeEntry: Store, private store: Store, private actionsSubject$: ActionsSubject, private toastrService: ToastrService @@ -113,6 +119,15 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { technologies: [], activity_id: head(this.activities).id, }; + this.canMarkEntryAsWIP = false; + this.storeEntry.pipe(select(getTimeEntriesDataSource)).subscribe(ds => { + this.canMarkEntryAsWIP = Utils.isThereAnEntryRunning(ds.data); + }); + + if (this.canMarkEntryAsWIP){ + 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(() => { 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); + } +}