Skip to content

Commit d4f751b

Browse files
committed
fix: TT 649 Display last 5 10 projects below Project Selection input box
1 parent d617e1d commit d4f751b

File tree

7 files changed

+78
-12
lines changed

7 files changed

+78
-12
lines changed

src/app/modules/customer-management/components/projects/components/store/project.actions.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export enum ProjectActionTypes {
88
LOAD_CUSTOMER_PROJECTS = '[Projects] LOAD_CUSTOMER_PROJECTS',
99
LOAD_CUSTOMER_PROJECTS_SUCCESS = '[Projects] LOAD_CUSTOMER_PROJECTS_SUCCESS',
1010
LOAD_CUSTOMER_PROJECTS_FAIL = '[Projects] LOAD_CUSTOMER_PROJECTS_FAIL',
11+
LOAD_RECENT_PROJECTS = '[Projects] LOAD_RECENT_PROJECTS',
1112
LOAD_RECENT_PROJECTS_SUCCESS = '[Projects] LOAD_RECENT_PROJECTS_SUCCESS',
1213
LOAD_RECENT_PROJECTS_FAIL = '[Projects] LOAD_RECENT_PROJECTS_FAIL',
1314
CREATE_PROJECT = '[Projects] CREATE_PROJECT',
@@ -63,6 +64,11 @@ export class LoadCustomerProjectsFail implements Action {
6364
constructor(public error: string) {}
6465
}
6566

67+
export class LoadRecentProjects implements Action {
68+
public readonly type = ProjectActionTypes.LOAD_RECENT_PROJECTS;
69+
constructor() {}
70+
}
71+
6672
export class LoadRecentProjectsSuccess implements Action {
6773
readonly type = ProjectActionTypes.LOAD_RECENT_PROJECTS_SUCCESS;
6874
constructor(readonly payload: Project[]) {}
@@ -168,6 +174,7 @@ export type ProjectActions =
168174
| LoadCustomerProjectsSuccess
169175
| LoadCustomerProjectsFail
170176
| LoadRecentProjectsSuccess
177+
| LoadRecentProjects
171178
| LoadRecentProjectsFail
172179
| CreateProject
173180
| CreateProjectSuccess

src/app/modules/customer-management/components/projects/components/store/project.effects.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ describe('ProjectEffects', () => {
5656
});
5757

5858
it('action type is LOAD_RECENT_PROJECTS_SUCCESS when service is executed sucessfully', async () => {
59-
actions$ = of({ type: ProjectActionTypes.LOAD_PROJECTS });
59+
actions$ = of({ type: ProjectActionTypes.LOAD_RECENT_PROJECTS });
6060
const serviceSpy = spyOn(service, 'getRecentProjects');
6161
serviceSpy.and.returnValue(of(projects));
6262

@@ -66,7 +66,7 @@ describe('ProjectEffects', () => {
6666
});
6767

6868
it('action type is LOAD_RECENT_PROJECTS_FAIL when service fail in execution', async () => {
69-
actions$ = of({ type: ProjectActionTypes.LOAD_PROJECTS });
69+
actions$ = of({ type: ProjectActionTypes.LOAD_RECENT_PROJECTS });
7070
const serviceSpy = spyOn(service, 'getRecentProjects');
7171
serviceSpy.and.returnValue(throwError({ error: { message: 'fail!' } }));
7272
spyOn(toastrService, 'error');

src/app/modules/customer-management/components/projects/components/store/project.effects.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export class ProjectEffects {
5151

5252
@Effect()
5353
loadRecentProjects$: Observable<Action> = this.actions$.pipe(
54-
ofType(actions.ProjectActionTypes.LOAD_PROJECTS),
54+
ofType(actions.ProjectActionTypes.LOAD_RECENT_PROJECTS),
5555
mergeMap(() =>
5656
this.projectService.getRecentProjects().pipe(
5757
map((projects) => {

src/app/modules/customer-management/components/projects/components/store/project.reducer.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ describe('projectReducer', () => {
6060
expect(state.customerProjects).toEqual([]);
6161
});
6262

63+
it('on LoadRecentProjects, isLoading is true', () => {
64+
const action = new actions.LoadRecentProjects();
65+
const state = projectReducer(initialState, action);
66+
expect(state.isLoading).toEqual(true);
67+
});
68+
6369
it('on LoadRecentProjectsSuccess, projectsFound are saved in the store', () => {
6470
const projectsFound: Project[] = [{ id: '1', name: 'abc', description: 'xxx', status: 'active' }];
6571
const newState = initialState;

src/app/modules/customer-management/components/projects/components/store/project.reducer.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const projectReducer = (state: ProjectState = initialState, action: Proje
3232
return {
3333
...state,
3434
projects: action.payload,
35-
isLoading: false
35+
isLoading: false,
3636
};
3737

3838
case ProjectActionTypes.LOAD_PROJECTS_FAIL: {
@@ -67,11 +67,17 @@ export const projectReducer = (state: ProjectState = initialState, action: Proje
6767
};
6868
}
6969

70+
case ProjectActionTypes.LOAD_RECENT_PROJECTS:
71+
return {
72+
...state,
73+
isLoading: true,
74+
};
75+
7076
case ProjectActionTypes.LOAD_RECENT_PROJECTS_SUCCESS:
7177
return {
7278
...state,
7379
recentProjects: action.payload,
74-
isLoading: false
80+
isLoading: false,
7581
};
7682

7783
case ProjectActionTypes.LOAD_RECENT_PROJECTS_FAIL: {

src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.html

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
<form [formGroup]="projectsForm">
23
<div class="form-group">
34
<label>Project:</label>
@@ -11,7 +12,7 @@
1112
(search)="onSearch($event)"
1213
(change)="onSelect($event)"
1314
(close)="loadActiveTimeEntry()">
14-
15+
1516
<ng-template ng-option-tmp let-item="item">
1617
<div class="flex flex-wrap flex-row justify-between">
1718
<div class="p-2 text-xs">
@@ -42,3 +43,46 @@
4243
</div>
4344
</div>
4445
</form>
46+
47+
<div class="table-responsive">
48+
<table class="table table-sm table-striped table-bordered mb-0">
49+
<thead class="thead-blue">
50+
<tr class="d-flex">
51+
<th class="col md-col">Latest projects you worked on</th>
52+
</tr>
53+
</thead>
54+
<tbody>
55+
<tr class="d-flex" *ngFor="let item of listRecentProjects" >
56+
<td class="col md-col">
57+
<div class="flex flex-wrap flex-row justify-between">
58+
<div class="p-2 text-xs">
59+
<span>{{item.customer.name}}</span> -
60+
<strong><span>{{item.name}}</span></strong>
61+
</div>
62+
<div class="p-1 pr-2">
63+
<button
64+
*ngIf="showClockIn"
65+
class="btn btn-sm btn-primary btn-select"
66+
(click)="clockIn(item.id, item.customer.name, item.name)"
67+
>
68+
Clock In
69+
</button>
70+
<button
71+
*ngIf="!showClockIn"
72+
class="btn btn-sm btn-primary btn-select"
73+
(click)="switch(item.id, item.customer.name, item.name)"
74+
>
75+
Switch</button
76+
>&nbsp;
77+
<button *ngIf="!showClockIn" class="btn btn-sm btn-update btn-select" (click)="updateProject(item.id)">
78+
Update project
79+
</button>
80+
</div>
81+
</div>
82+
</td>
83+
</tr>
84+
</tbody>
85+
86+
</table>
87+
<br>
88+
</div>

src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,10 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy {
6868
this.activities = response;
6969
});
7070

71-
this.store.dispatch(new actions.LoadProjects());
71+
this.store.dispatch(new actions.LoadRecentProjects());
7272
const recentProjects$ = this.store.pipe(select(getRecentProjects));
7373
this.recentProjectsSubscription = recentProjects$.subscribe((projects) => {
74-
if (projects?.length > 0) {
75-
this.listRecentProjects = projects;
76-
}else{
77-
this.listRecentProjects = this.listProjects;
78-
}
74+
this.listRecentProjects = projects;
7975
this.listProjectsShowed = this.listRecentProjects;
8076
});
8177

@@ -119,19 +115,26 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy {
119115
};
120116
this.store.dispatch(new entryActions.ClockIn(entry));
121117
this.projectsForm.setValue({ project_id: `${customerName} - ${name}` });
118+
setTimeout(() => {
119+
this.store.dispatch(new actions.LoadRecentProjects());
120+
}, 2000);
122121
}
123122

124123
updateProject(selectedProject) {
125124
const entry = { id: this.activeEntry.id, project_id: selectedProject };
126125
this.store.dispatch(new entryActions.UpdateEntryRunning(entry));
127126
this.store.dispatch(new entryActions.LoadActiveEntry());
127+
this.store.dispatch(new actions.LoadRecentProjects());
128128
}
129129

130130
switch(selectedProject, customerName, name) {
131131
if (this.activeEntry.activity_id === null) {
132132
this.toastrService.error('Before switching, please select an activity');
133133
} else {
134134
this.store.dispatch(new entryActions.SwitchTimeEntry(this.activeEntry.id, selectedProject));
135+
setTimeout(() => {
136+
this.store.dispatch(new actions.LoadRecentProjects());
137+
}, 2000);
135138
this.projectsForm.setValue({ project_id: `${customerName} - ${name}` });
136139
}
137140
}

0 commit comments

Comments
 (0)