Skip to content

Commit dda90c6

Browse files
authored
Merge pull request ioet#386 from ioet/368-clean-form-sfter-saving-data
closes: ioet#368 closes ioet#377
2 parents 22f2ac0 + d1c7faa commit dda90c6

File tree

5 files changed

+63
-29
lines changed

5 files changed

+63
-29
lines changed

src/app/modules/shared/components/details-fields/details-fields.component.spec.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { EntryActionTypes } from './../../../time-clock/store/entry.actions';
12
import { TechnologiesComponent } from './../technologies/technologies.component';
23
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
34
import { provideMockStore, MockStore } from '@ngrx/store/testing';
45
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
56
import { DatePipe, formatDate } from '@angular/common';
7+
import { ActionsSubject } from '@ngrx/store';
68

79
import { TechnologyState } from '../../store/technology.reducers';
810
import { allTechnologies } from '../../store/technology.selectors';
@@ -24,21 +26,22 @@ describe('DetailsFieldsComponent', () => {
2426
let mockEntriesCreateErrorSelector;
2527
let entryToEdit;
2628
let formValues;
29+
const actionSub: ActionsSubject = new ActionsSubject();
2730

2831
const state = {
2932
projects: {
30-
projects: [{id: 'id', name: 'name', project_type_id: ''}],
31-
customerProjects: [{id: 'id', name: 'name', description: 'description', project_type_id: '123'}],
33+
projects: [{ id: 'id', name: 'name', project_type_id: '' }],
34+
customerProjects: [{ id: 'id', name: 'name', description: 'description', project_type_id: '123' }],
3235
isLoading: false,
3336
message: '',
3437
projectToEdit: undefined,
3538
},
3639
technologies: {
37-
technologyList: {items: [{name: 'java'}]},
40+
technologyList: { items: [{ name: 'java' }] },
3841
isLoading: false,
3942
},
4043
activities: {
41-
data: [{id: 'fc5fab41-a21e-4155-9d05-511b956ebd05', tenant_id: 'ioet', deleted: null, name: 'abc'}],
44+
data: [{ id: 'fc5fab41-a21e-4155-9d05-511b956ebd05', tenant_id: 'ioet', deleted: null, name: 'abc' }],
4245
isLoading: false,
4346
message: 'Data fetch successfully!',
4447
activityIdToEdit: '',
@@ -63,7 +66,7 @@ describe('DetailsFieldsComponent', () => {
6366
beforeEach(async(() => {
6467
TestBed.configureTestingModule({
6568
declarations: [DetailsFieldsComponent, TechnologiesComponent],
66-
providers: [provideMockStore({initialState: state})],
69+
providers: [provideMockStore({ initialState: state }), { provide: ActionsSubject, useValue: actionSub }],
6770
imports: [FormsModule, ReactiveFormsModule],
6871
}).compileComponents();
6972
store = TestBed.inject(MockStore);
@@ -102,6 +105,24 @@ describe('DetailsFieldsComponent', () => {
102105
expect(component).toBeTruthy();
103106
});
104107

108+
[
109+
{ actionType: EntryActionTypes.CREATE_ENTRY_SUCCESS },
110+
{ actionType: EntryActionTypes.UPDATE_ENTRY_SUCCESS },
111+
].map((param) => {
112+
it(`cleanForm after an action type ${param.actionType} is received`, () => {
113+
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
114+
const action = {
115+
type: param.actionType,
116+
};
117+
spyOn(component, 'cleanForm');
118+
119+
component.ngOnInit();
120+
actionSubject.next(action);
121+
122+
expect(component.cleanForm).toHaveBeenCalled();
123+
});
124+
});
125+
105126
it('should emit ngOnChange without data', () => {
106127
component.entryToEdit = null;
107128
component.ngOnChanges();
@@ -231,23 +252,23 @@ describe('DetailsFieldsComponent', () => {
231252
});
232253

233254
it('when editing entry that is currently running, then the entry should be marked as running', () => {
234-
component.entryToEdit = {...entryToEdit, running: true};
255+
component.entryToEdit = { ...entryToEdit, running: true };
235256

236257
fixture.componentInstance.ngOnChanges();
237258

238259
expect(component.isEntryRunning).toBeTrue();
239260
});
240261

241262
it('when editing entry that already finished, then the entry should not be marked as running', () => {
242-
component.entryToEdit = {...entryToEdit, running: false};
263+
component.entryToEdit = { ...entryToEdit, running: false };
243264

244265
fixture.componentInstance.ngOnChanges();
245266

246267
expect(component.isEntryRunning).toBeFalse();
247268
});
248269

249270
it('when editing entry that already finished, then the entry should not be marked as running', () => {
250-
component.entryToEdit = {...entryToEdit, running: false};
271+
component.entryToEdit = { ...entryToEdit, running: false };
251272

252273
fixture.componentInstance.ngOnChanges();
253274

@@ -259,7 +280,7 @@ describe('DetailsFieldsComponent', () => {
259280
spyOn(component, 'getElapsedSeconds').and.returnValue('10');
260281
spyOn(component.saveEntry, 'emit');
261282

262-
component.entryForm.setValue({...formValues, entry_date: '2020-06-11'});
283+
component.entryForm.setValue({ ...formValues, entry_date: '2020-06-11' });
263284
component.onSubmit();
264285
const data = {
265286
project_id: '',

src/app/modules/shared/components/details-fields/details-fields.component.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { EntryActionTypes } from './../../../time-clock/store/entry.actions';
2+
import { filter } from 'rxjs/operators';
13
import { NumberFormatter } from './../../formatters/number.formatter';
24
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild, } from '@angular/core';
35
import { FormBuilder, FormGroup } from '@angular/forms';
4-
import { select, Store } from '@ngrx/store';
6+
import { select, Store, ActionsSubject } from '@ngrx/store';
57
import { formatDate } from '@angular/common';
68

79
import { Activity, Entry, Project } from '../../models';
@@ -33,7 +35,7 @@ export class DetailsFieldsComponent implements OnChanges, OnInit {
3335
activities: Activity[] = [];
3436
isEntryRunning = false;
3537

36-
constructor(private formBuilder: FormBuilder, private store: Store<Merged>) {
38+
constructor(private formBuilder: FormBuilder, private store: Store<Merged>, private actionsSubject$: ActionsSubject) {
3739
this.entryForm = this.formBuilder.group({
3840
project_id: '',
3941
activity_id: '',
@@ -73,6 +75,15 @@ export class DetailsFieldsComponent implements OnChanges, OnInit {
7375
this.closeEntryModal();
7476
}
7577
});
78+
79+
this.actionsSubject$.pipe(
80+
filter((action: any) => (
81+
action.type === EntryActionTypes.CREATE_ENTRY_SUCCESS ||
82+
action.type === EntryActionTypes.UPDATE_ENTRY_SUCCESS
83+
))
84+
).subscribe(() => {
85+
this.cleanForm();
86+
});
7687
}
7788

7889
ngOnChanges(): void {

src/app/modules/time-clock/store/entry.reducer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export const entryReducer = (state: EntryState = initialState, action: EntryActi
100100
entryList.sort((a, b) => new Date(b.start_date).getTime() - new Date(a.start_date).getTime());
101101
return {
102102
...state,
103-
active: action.payload,
104103
entryList,
105104
isLoading: false,
106105
createError: false,
@@ -156,6 +155,7 @@ export const entryReducer = (state: EntryState = initialState, action: EntryActi
156155
entryList.sort((a, b) => new Date(b.start_date).getTime() - new Date(a.start_date).getTime());
157156
return {
158157
...state,
158+
entryList,
159159
isLoading: false,
160160
updateError: false,
161161
};

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

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { LoadActiveEntry } from './../../time-clock/store/entry.actions';
12
import { ToastrService } from 'ngx-toastr';
23
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
34
import { provideMockStore, MockStore } from '@ngrx/store/testing';
@@ -100,6 +101,14 @@ describe('TimeEntriesComponent', () => {
100101
fixture.destroy();
101102
});
102103

104+
it('dispatch an action on loadActiveEntry', () => {
105+
spyOn(store, 'dispatch');
106+
107+
component.loadActiveEntry();
108+
109+
expect(store.dispatch).toHaveBeenCalledWith(new LoadActiveEntry());
110+
});
111+
103112
it('should be created', () => {
104113
expect(component).toBeTruthy();
105114
});
@@ -250,16 +259,4 @@ describe('TimeEntriesComponent', () => {
250259
expect(component.doSave).toHaveBeenCalledWith(entryToSave);
251260
}));
252261

253-
it('when saving time entries, the time entries should be queried', () => {
254-
const currentMonth = new Date().getMonth() + 1;
255-
const entryToSave = {
256-
project_id: 'project-id'
257-
};
258-
component.activeTimeEntry = null;
259-
spyOn(store, 'dispatch');
260-
261-
component.saveEntry(entryToSave);
262-
263-
expect(store.dispatch).toHaveBeenCalledWith(new entryActions.LoadEntries(currentMonth));
264-
});
265262
});

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ export class TimeEntriesComponent implements OnInit {
2626
dataByMonth$.subscribe((response) => {
2727
this.dataByMonth = response;
2828
});
29-
this.store.dispatch(new entryActions.LoadActiveEntry());
30-
this.store.pipe(select(getActiveTimeEntry)).subscribe((activeTimeEntry) => {
31-
this.activeTimeEntry = activeTimeEntry;
32-
});
29+
this.loadActiveEntry();
3330
}
3431

3532
newEntry() {
@@ -65,7 +62,15 @@ export class TimeEntriesComponent implements OnInit {
6562
} else {
6663
this.store.dispatch(new entryActions.CreateEntry(entry));
6764
}
68-
this.store.dispatch(new entryActions.LoadEntries(new Date().getMonth() + 1));
65+
}
66+
67+
loadActiveEntry() {
68+
this.store.dispatch(new entryActions.LoadActiveEntry());
69+
this.store.pipe(select(getActiveTimeEntry)).subscribe((activeTimeEntry) => {
70+
if (activeTimeEntry) {
71+
this.activeTimeEntry = activeTimeEntry;
72+
}
73+
});
6974
}
7075

7176
removeEntry(entryId: string) {

0 commit comments

Comments
 (0)