Skip to content

Commit 07d5f9d

Browse files
committed
fix: #320 reload time worked summary after clocking-out
1 parent df64036 commit 07d5f9d

File tree

5 files changed

+71
-10
lines changed

5 files changed

+71
-10
lines changed

src/app/modules/shared/pipes/substract-date/substract-date.pipe.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ describe('SubstractDatePipe', () => {
1515
expect(diff).toBe('02:20');
1616
});
1717

18+
it('returns the date diff using hh:mm:ss for a diff < 1 min when displaySeconds is true', () => {
19+
const fromDate = new Date('2011-04-11T10:22:40Z');
20+
const substractDate = new Date('2011-04-11T10:20:30Z');
21+
22+
const diff = new SubstractDatePipe().transform(fromDate, substractDate, true);
23+
24+
expect(diff).toBe('00:02:10');
25+
});
26+
1827
it('returns the date diff including seconds if difference is less than a minute', () => {
1928
const fromDate = new Date('2011-04-11T10:20:40Z');
2029
const substractDate = new Date('2011-04-11T10:20:30Z');

src/app/modules/shared/pipes/substract-date/substract-date.pipe.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as moment from 'moment';
66
})
77
export class SubstractDatePipe implements PipeTransform {
88

9-
transform(fromDate: Date, substractDate: Date): string {
9+
transform(fromDate: Date, substractDate: Date, displaySeconds: boolean = false): string {
1010

1111
if (fromDate === null || substractDate === null ) {
1212
return '--:--';
@@ -16,7 +16,7 @@ export class SubstractDatePipe implements PipeTransform {
1616
let endDate = moment(fromDate, 'YYYY-MM-DD HH:mm:ss');
1717
let duration: moment.Duration = moment.duration(endDate.diff(startDate));
1818

19-
if (duration.asSeconds() > 60) {
19+
if (duration.asSeconds() > 60 && !displaySeconds) {
2020
endDate = endDate.add(1, 'minute').startOf('minute');
2121
duration = moment.duration(endDate.diff(startDate));
2222
return `${ this.formatTime(duration.hours())}:${this.formatTime(duration.minutes()) }`;

src/app/modules/time-clock/components/time-entries-summary/time-entries-summary.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export class TimeEntriesSummaryComponent implements OnInit, OnDestroy {
9191
this.timeInterval = interval(1000).pipe(
9292
takeUntil(this.destroyed$)
9393
).subscribe(() => {
94-
this.currentWorkingTime = new SubstractDatePipe().transform(new Date(), new Date(entry.start_date));
94+
this.currentWorkingTime = new SubstractDatePipe().transform(new Date(), new Date(entry.start_date), true);
9595
});
9696
}
9797
}

src/app/modules/time-clock/pages/time-clock.component.spec.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { FormBuilder } from '@angular/forms';
2-
import { StopTimeEntryRunning } from './../store/entry.actions';
2+
import { StopTimeEntryRunning, EntryActionTypes, LoadEntriesSummary } from './../store/entry.actions';
33
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
44
import { HttpClientTestingModule } from '@angular/common/http/testing';
55
import { provideMockStore, MockStore } from '@ngrx/store/testing';
@@ -8,12 +8,15 @@ import { ProjectState } from '../../customer-management/components/projects/comp
88
import { ProjectListHoverComponent } from '../components';
99
import { FilterProjectPipe } from '../../shared/pipes';
1010
import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service';
11+
import { ActionsSubject } from '@ngrx/store';
1112

1213
describe('TimeClockComponent', () => {
1314
let component: TimeClockComponent;
1415
let fixture: ComponentFixture<TimeClockComponent>;
1516
let store: MockStore<ProjectState>;
1617
let azureAdB2CService: AzureAdB2CService;
18+
const actionSub: ActionsSubject = new ActionsSubject();
19+
1720
const state = {
1821
projects: {
1922
projects: [{ id: 'id', name: 'name', project_type_id: '' }],
@@ -46,6 +49,7 @@ describe('TimeClockComponent', () => {
4649
FormBuilder,
4750
AzureAdB2CService,
4851
provideMockStore({ initialState: state }),
52+
{ provide: ActionsSubject, useValue: actionSub },
4953
],
5054
}).compileComponents();
5155
store = TestBed.inject(MockStore);
@@ -62,6 +66,34 @@ describe('TimeClockComponent', () => {
6266
expect(component).toBeTruthy();
6367
});
6468

69+
it('on STOP_TIME_ENTRY_RUNNING_SUCCESS summaries are reloaded', () => {
70+
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
71+
const action = {
72+
type: EntryActionTypes.STOP_TIME_ENTRY_RUNNING_SUCCESS
73+
};
74+
spyOn(store, 'dispatch');
75+
76+
actionSubject.next(action);
77+
78+
expect(store.dispatch).toHaveBeenCalledWith(new LoadEntriesSummary());
79+
});
80+
81+
it('register reloadSummaries on ngOnInit', () => {
82+
spyOn(component, 'reloadSummariesOnClockOut');
83+
84+
component.ngOnInit();
85+
86+
expect(component.reloadSummariesOnClockOut).toHaveBeenCalled();
87+
});
88+
89+
it('unsubscribe clockOutSubscription onDestroy', () => {
90+
spyOn(component.clockOutSubscription, 'unsubscribe');
91+
92+
component.ngOnDestroy();
93+
94+
expect(component.clockOutSubscription.unsubscribe).toHaveBeenCalled();
95+
});
96+
6597
it('onInit checks if isLogin and gets the userName', () => {
6698
spyOn(azureAdB2CService, 'isLogin').and.returnValue(true);
6799
spyOn(azureAdB2CService, 'getName').and.returnValue('Name');

src/app/modules/time-clock/pages/time-clock.component.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import { filter } from 'rxjs/operators';
12
import { getActiveTimeEntry } from './../store/entry.selectors';
2-
import { StopTimeEntryRunning } from './../store/entry.actions';
3+
import { StopTimeEntryRunning, EntryActionTypes, LoadEntriesSummary } from './../store/entry.actions';
34
import { Entry } from './../../shared/models/entry.model';
4-
import { Store, select } from '@ngrx/store';
5-
import { Component, OnInit } from '@angular/core';
5+
import { Store, select, ActionsSubject } from '@ngrx/store';
6+
import { Component, OnInit, OnDestroy } from '@angular/core';
67
import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service';
78
import { Subscription } from 'rxjs';
89

@@ -11,13 +12,18 @@ import { Subscription } from 'rxjs';
1112
templateUrl: './time-clock.component.html',
1213
styleUrls: ['./time-clock.component.scss'],
1314
})
14-
export class TimeClockComponent implements OnInit {
15+
export class TimeClockComponent implements OnInit, OnDestroy {
1516
username: string;
1617
areFieldsVisible = false;
1718
activeTimeEntry: Entry;
18-
actionsSubscription: Subscription;
19+
clockOutSubscription: Subscription;
1920

20-
constructor(private azureAdB2CService: AzureAdB2CService, private store: Store<Entry>) {
21+
constructor(private azureAdB2CService: AzureAdB2CService, private store: Store<Entry>,
22+
private actionsSubject$: ActionsSubject) {
23+
}
24+
25+
ngOnDestroy(): void {
26+
this.clockOutSubscription.unsubscribe();
2127
}
2228

2329
ngOnInit() {
@@ -30,6 +36,20 @@ export class TimeClockComponent implements OnInit {
3036
this.areFieldsVisible = false;
3137
}
3238
});
39+
40+
this.reloadSummariesOnClockOut();
41+
42+
}
43+
44+
reloadSummariesOnClockOut() {
45+
this.clockOutSubscription = this.actionsSubject$.pipe(
46+
filter((action) => (
47+
action.type === EntryActionTypes.STOP_TIME_ENTRY_RUNNING_SUCCESS
48+
)
49+
)
50+
).subscribe( (action) => {
51+
this.store.dispatch(new LoadEntriesSummary());
52+
});
3353
}
3454

3555
clockOut() {

0 commit comments

Comments
 (0)