Skip to content

Commit 13399b9

Browse files
committed
feat: TTL-910 add project dropdown
1 parent bd0d48a commit 13399b9

File tree

7 files changed

+82
-4
lines changed

7 files changed

+82
-4
lines changed

src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ import { TimeRangeOptionsComponent } from './modules/reports/components/time-ran
101101
import { V2RedirectComponent } from './modules/v2-redirect/v2-redirect.component';
102102
import { SpinnerOverlayComponent } from './modules/shared/components/spinner-overlay/spinner-overlay.component';
103103
import { SpinnerInterceptor } from './modules/shared/interceptors/spinner.interceptor';
104+
import { SearchProjectComponent } from './modules/shared/components/search-project/search-project.component';
104105

105106
const maskConfig: Partial<IConfig> = {
106107
validation: false,
@@ -142,6 +143,7 @@ const maskConfig: Partial<IConfig> = {
142143
SubstractDatePipeDisplayAsFloat,
143144
TechnologiesComponent,
144145
SearchUserComponent,
146+
SearchProjectComponent,
145147
TimeEntriesSummaryComponent,
146148
TimeDetailsPipe,
147149
InputLabelComponent,

src/app/modules/reports/components/time-entries-table/time-entries-table.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div class="row scroll-table mt-5 ml-0">
22
<app-search-user [users]="users" (selectedUserId)="user($event)"></app-search-user>
3-
3+
<app-search-project [projects]="listProjects" (selectedProjectId)="project($event)"></app-search-project>
44
<table
55
class="table table-striped mb-0"
66
datatable

src/app/modules/reports/components/time-entries-table/time-entries-table.component.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import { DataTableDirective } from 'angular-datatables';
55
import * as moment from 'moment';
66
import { Observable, Subject, Subscription } from 'rxjs';
77
import { filter } from 'rxjs/operators';
8-
import { Entry } from 'src/app/modules/shared/models';
8+
import { Entry, Project } from 'src/app/modules/shared/models';
99
import { DataSource } from 'src/app/modules/shared/models/data-source.model';
1010
import { EntryState } from '../../../time-clock/store/entry.reducer';
1111
import { getReportDataSource, getResultSumEntriesSelected } from '../../../time-clock/store/entry.selectors';
1212
import { TotalHours } from '../../models/total-hours-report';
1313
import { User } from 'src/app/modules/users/models/users';
1414
import { LoadUsers, UserActionTypes } from 'src/app/modules/users/store/user.actions';
1515
import { ParseDateTimeOffset } from '../../../shared/formatters/parse-date-time-offset/parse-date-time-offset';
16+
import { LoadProjects, ProjectActionTypes } from 'src/app/modules/customer-management/components/projects/components/store/project.actions';
1617

1718
@Component({
1819
selector: 'app-time-entries-table',
@@ -21,11 +22,13 @@ import { ParseDateTimeOffset } from '../../../shared/formatters/parse-date-time-
2122
})
2223
export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewInit {
2324
@Output() selectedUserId = new EventEmitter<string>();
25+
@Output() selectedProjectId = new EventEmitter<string>();
2426

2527
selectOptionValues = [15, 30, 50, 100, -1];
2628
selectOptionNames = [15, 30, 50, 100, 'All'];
2729
totalTimeSelected: moment.Duration;
2830
users: User[] = [];
31+
projects: Project[] = [];
2932
removeFirstColumn = 'th:not(:first)';
3033

3134
dtOptions: any = {
@@ -82,9 +85,13 @@ export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewIn
8285
resultSumEntriesSelected$: Observable<TotalHours>;
8386
totalHoursSubscription: Subscription;
8487
dateTimeOffset: ParseDateTimeOffset;
88+
listProjects: Project[] = [];
8589

86-
87-
constructor(private store: Store<EntryState>, private actionsSubject$: ActionsSubject, private storeUser: Store<User> ) {
90+
constructor(private store: Store<EntryState>,
91+
private actionsSubject$: ActionsSubject,
92+
private storeUser: Store<User>,
93+
private storeProject: Store<Project>
94+
) {
8895
this.reportDataSource$ = this.store.pipe(select(getReportDataSource));
8996
this.resultSumEntriesSelected$ = this.store.pipe(select(getResultSumEntriesSelected));
9097
this.dateTimeOffset = new ParseDateTimeOffset();
@@ -102,6 +109,23 @@ export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewIn
102109
});
103110
}
104111

112+
uploadProjects(): void {
113+
this.storeProject.dispatch(new LoadProjects());
114+
this.actionsSubject$
115+
.pipe(filter((action: any) => action.type === ProjectActionTypes.LOAD_PROJECTS_SUCCESS))
116+
.subscribe((action) => {
117+
const sortProjects = [...action.payload];
118+
sortProjects.sort((a, b) => a.name.localeCompare(b.name));
119+
this.projects = sortProjects;
120+
this.projects = this.projects.filter(project => project.status === 'active');
121+
this.projects.forEach((project) => {
122+
const projectWithSearchField = { ...project };
123+
projectWithSearchField.search_field = `${project.customer.name} - ${project.name}`;
124+
this.listProjects.push(projectWithSearchField);
125+
});
126+
});
127+
}
128+
105129
ngOnInit(): void {
106130
this.rerenderTableSubscription = this.reportDataSource$.subscribe((ds) => {
107131
this.totalHoursSubscription = this.resultSumEntriesSelected$.subscribe((actTotalHours) => {
@@ -112,6 +136,7 @@ export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewIn
112136
this.rerenderDataTable();
113137
});
114138
this.uploadUsers();
139+
this.uploadProjects();
115140
}
116141

117142
ngAfterViewInit(): void {
@@ -172,6 +197,10 @@ export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewIn
172197
this.selectedUserId.emit(userId);
173198
}
174199

200+
project(projectId: string) {
201+
this.selectedProjectId.emit(projectId);
202+
}
203+
175204
sumHoursEntriesSelected(entry: Entry, checked: boolean){
176205
this.resultSumEntriesSelected = new TotalHours();
177206
const duration = moment.duration(moment(entry.end_date).diff(moment(entry.start_date)));

src/app/modules/reports/pages/reports.component.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,16 @@ import { Component } from '@angular/core';
88
export class ReportsComponent {
99

1010
userId: string;
11+
projectId: string;
12+
activityId: string;
1113

1214
user(userId: string){
1315
this.userId = userId;
1416
}
17+
activity(activityId: string){
18+
this.activityId = activityId;
19+
}
20+
project(projectId: string){
21+
this.projectId = projectId;
22+
}
1523
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div class="form-group" >
2+
<label>Projects: </label>
3+
4+
<ng-select [(ngModel)]="selectedProject" [multiple]="false" placeholder="Select project" (change)="updateProject()" class="selectProject">
5+
<ng-option *ngFor="let project of projects" value={{project.id}}> <strong>{{project.customer.name}}</strong> - {{project.name}}</ng-option >
6+
</ng-select>
7+
8+
</div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
label {
2+
width: 225px;
3+
}
4+
.selectProject {
5+
display: inline-block;
6+
width: 350px;
7+
padding: 0 12px 15px 12px;
8+
}
9+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Component, EventEmitter, Input, Output } from '@angular/core';
2+
3+
@Component({
4+
selector: 'app-search-project',
5+
templateUrl: './search-project.component.html',
6+
styleUrls: ['./search-project.component.scss'],
7+
})
8+
9+
export class SearchProjectComponent {
10+
11+
readonly ALLOW_SELECT_MULTIPLE = false;
12+
selectedProject: string[];
13+
14+
@Input() projects: string[] = [];
15+
16+
@Output() selectedProjectId = new EventEmitter<string[] | string>();
17+
18+
updateProject() {
19+
this.selectedProjectId.emit(this.selectedProject.length === 0 ? '*' : this.selectedProject);
20+
}
21+
}
22+

0 commit comments

Comments
 (0)