diff --git a/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.html b/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.html index faa31f7fc..7f0815df7 100644 --- a/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.html +++ b/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.html @@ -1,16 +1,20 @@
Summary

-
+
+
Current
+

{{ currentWorkingTime }}

+
+
Day
-

{{ timeEntriesSummary.day | timeDetails }}

+

{{ timeEntriesSummary?.day | timeDetails }}

-
+
Week
-

{{ timeEntriesSummary.week | timeDetails }}

+

{{ timeEntriesSummary?.week | timeDetails }}

-
+
Month
-

{{ timeEntriesSummary.month | timeDetails }}

+

{{ timeEntriesSummary?.month | timeDetails }}

diff --git a/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.spec.ts b/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.spec.ts index 488267546..1d8f6ae7c 100644 --- a/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.spec.ts +++ b/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.spec.ts @@ -1,23 +1,44 @@ +import { EntryState } from './../../store/entry.reducer'; import { TimeDetailsPipe } from './../../pipes/time-details.pipe'; -import { provideMockStore } from '@ngrx/store/testing'; +import { provideMockStore, MockStore } from '@ngrx/store/testing'; import { TimeEntriesSummary } from './../../models/time.entry.summary'; import { TimeDetails } from './../../models/time.entry.summary'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed, tick, fakeAsync, discardPeriodicTasks } from '@angular/core/testing'; import { TimeEntriesSummaryComponent } from './time-entries-summary.component'; describe('TimeEntriesSummaryComponent', () => { let component: TimeEntriesSummaryComponent; let fixture: ComponentFixture; - + let store: MockStore; const emptyTimeDetails: TimeDetails = { hours: '--:--', minutes: '--:--', seconds: '--:--' }; const emptyTimeEntriesSummary: TimeEntriesSummary = { day: emptyTimeDetails, week: emptyTimeDetails, month: emptyTimeDetails }; + const timeTwoHoursBehind = new Date(); + timeTwoHoursBehind.setHours(timeTwoHoursBehind.getHours() - 2); + + const timeEntry = { + id: '123', + start_date: timeTwoHoursBehind, + end_date: null, + activity_id: '123', + technologies: ['react', 'redux'], + comments: 'any comment', + uri: 'custom uri', + project_id: '123' + }; + const state = { - entries: { - timeEntriesSummary: emptyTimeEntriesSummary - }, + active: timeEntry, + entryList: [timeEntry], + entries: [timeEntry], + isLoading: false, + message: '', + createError: false, + updateError: false, + timeEntriesSummary: emptyTimeEntriesSummary, + entriesForReport: [timeEntry], }; beforeEach(async(() => { @@ -27,15 +48,38 @@ describe('TimeEntriesSummaryComponent', () => { ], }) .compileComponents(); + store = TestBed.inject(MockStore); })); beforeEach(() => { fixture = TestBed.createComponent(TimeEntriesSummaryComponent); component = fixture.componentInstance; fixture.detectChanges(); + store.setState(state); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('dispatches two actions on ngOnInit', () => { + spyOn(store, 'dispatch'); + + component.ngOnInit(); + + expect(store.dispatch).toHaveBeenCalledTimes(2); + }); + + it('runs the time on updateCurrentWorkingHours', fakeAsync(() => { + component.updateCurrentWorkingHours(timeEntry); + + tick(1100); + fixture.detectChanges(); + + const elapsedTime = component.currentWorkingTime; + const isElapsedTimeAtLeastTwoHours = elapsedTime.startsWith('02:00'); + expect(isElapsedTimeAtLeastTwoHours).toBe(true); + discardPeriodicTasks(); + })); + }); diff --git a/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts b/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts index f6e575d19..6dc06f00c 100644 --- a/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts +++ b/src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts @@ -1,6 +1,9 @@ -import { getEntriesSummary } from './../../store/entry.selectors'; +import { SubstractDatePipe } from './../../../shared/pipes/substract-date/substract-date.pipe'; +import { interval } from 'rxjs'; +import { Entry } from './../../../shared/models/entry.model'; +import { getEntriesSummary, getActiveTimeEntry } from './../../store/entry.selectors'; import { TimeEntriesSummary } from '../../models/time.entry.summary'; -import { LoadEntriesSummary } from './../../store/entry.actions'; +import { LoadEntriesSummary, LoadActiveEntry } from './../../store/entry.actions'; import { EntryState } from './../../store/entry.reducer'; import { Store, select } from '@ngrx/store'; import { Component, OnInit } from '@angular/core'; @@ -13,10 +16,19 @@ import { Component, OnInit } from '@angular/core'; export class TimeEntriesSummaryComponent implements OnInit { timeEntriesSummary: TimeEntriesSummary; + currentWorkingTime: string; constructor(private store: Store) { } ngOnInit(): void { + this.store.dispatch(new LoadActiveEntry()); + const activeTimeEntry$ = this.store.pipe(select(getActiveTimeEntry)); + activeTimeEntry$.subscribe((response) => { + if (response) { + this.updateCurrentWorkingHours(response); + } + }); + this.store.dispatch(new LoadEntriesSummary()); const timeEntriesSummary$ = this.store.pipe(select(getEntriesSummary)); timeEntriesSummary$.subscribe((response) => { @@ -24,4 +36,13 @@ export class TimeEntriesSummaryComponent implements OnInit { }); } + + updateCurrentWorkingHours(entry: Entry) { + const timeInterval = interval(1000); + timeInterval.subscribe(() => { + this.currentWorkingTime = + new SubstractDatePipe() + .transform(new Date(), new Date(entry.start_date)); + }); + } } diff --git a/src/app/modules/time-clock/pipes/time-details.pipe.spec.ts b/src/app/modules/time-clock/pipes/time-details.pipe.spec.ts index 59c9bb1c9..f31691631 100644 --- a/src/app/modules/time-clock/pipes/time-details.pipe.spec.ts +++ b/src/app/modules/time-clock/pipes/time-details.pipe.spec.ts @@ -1,3 +1,4 @@ +import { TimeDetails } from './../models/time.entry.summary'; import { TimeDetailsPipe } from './time-details.pipe'; describe('TimeDetailsPipe', () => { @@ -10,4 +11,21 @@ describe('TimeDetailsPipe', () => { const pipe = new TimeDetailsPipe(); expect(pipe.formatAsTwoDigit('5')).toBe('05'); }); + + it('returns the same data if number has 2 digits', () => { + const pipe = new TimeDetailsPipe(); + expect(pipe.formatAsTwoDigit('15')).toBe('15'); + }); + + it('formats hour in expected format', () => { + const timeDetails = { hours: '1', minutes: '9', seconds: '00'}; + const pipe = new TimeDetailsPipe(); + expect('01:09').toBe(pipe.transform(timeDetails)); + }); + + it('returns --:-- when timeDetails is null', () => { + const timeDetails = null; + const pipe = new TimeDetailsPipe(); + expect('--:--').toBe(pipe.transform(timeDetails)); + }); }); diff --git a/src/app/modules/time-clock/pipes/time-details.pipe.ts b/src/app/modules/time-clock/pipes/time-details.pipe.ts index d99a7e660..3c22557f6 100644 --- a/src/app/modules/time-clock/pipes/time-details.pipe.ts +++ b/src/app/modules/time-clock/pipes/time-details.pipe.ts @@ -7,7 +7,11 @@ import { Pipe, PipeTransform } from '@angular/core'; export class TimeDetailsPipe implements PipeTransform { transform(value: TimeDetails): string { - return `${this.formatAsTwoDigit(value.hours)}:${this.formatAsTwoDigit(value.minutes)}` ; + if (value) { + return `${this.formatAsTwoDigit(value.hours)}:${this.formatAsTwoDigit(value.minutes)}`; + } else { + return '--:--'; + } } formatAsTwoDigit(time: string): string {