+
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 {