Skip to content

Commit 601da91

Browse files
codigodehoywilc0519
authored andcommitted
feat: TT-593 add filter for searching a specific user
* Created user-search component * Loaded all users to the select * sent the user.id to the api reports
1 parent da1792f commit 601da91

File tree

10 files changed

+95
-13
lines changed

10 files changed

+95
-13
lines changed

src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ import { NgSelectModule } from '@ng-select/ng-select';
8989
import { DarkModeComponent } from './modules/shared/components/dark-mode/dark-mode.component';
9090
import { SocialLoginModule, SocialAuthServiceConfig } from 'angularx-social-login';
9191
import { GoogleLoginProvider } from 'angularx-social-login';
92+
import { SearchUserComponent } from './modules/shared/components/search-user/search-user.component';
9293

9394
const maskConfig: Partial<IConfig> = {
9495
validation: false,
@@ -128,6 +129,7 @@ const maskConfig: Partial<IConfig> = {
128129
EntryFieldsComponent,
129130
SubstractDatePipe,
130131
TechnologiesComponent,
132+
SearchUserComponent,
131133
TimeEntriesSummaryComponent,
132134
TimeDetailsPipe,
133135
InputLabelComponent,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<div class="row scroll-table mt-5 ml-0">
2+
<app-search-user [users]="users" (selectedUserId)="user($event)"></app-search-user>
23
<table
34
class="table table-striped mb-0"
45
datatable

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
import { formatDate } from '@angular/common';
2-
import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
2+
import { AfterViewInit, Component, EventEmitter, OnDestroy, Output, OnInit, ViewChild } from '@angular/core';
3+
import { DomSanitizer } from '@angular/platform-browser';
34
import { select, Store } from '@ngrx/store';
45
import { DataTableDirective } from 'angular-datatables';
56
import * as moment from 'moment';
67
import { Observable, Subject, Subscription } from 'rxjs';
8+
import { filter } from 'rxjs/operators';
79
import { Entry } from 'src/app/modules/shared/models';
810
import { DataSource } from 'src/app/modules/shared/models/data-source.model';
911
import { EntryState } from '../../../time-clock/store/entry.reducer';
1012
import { getReportDataSource } from '../../../time-clock/store/entry.selectors';
13+
import { ActionsSubject } from '@ngrx/store';
14+
import { User } from 'src/app/modules/users/models/users';
15+
import { LoadUsers, UserActionTypes } from 'src/app/modules/users/store/user.actions';
1116

1217
@Component({
1318
selector: 'app-time-entries-table',
1419
templateUrl: './time-entries-table.component.html',
1520
styleUrls: ['./time-entries-table.component.scss'],
1621
})
1722
export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewInit {
23+
@Output() selectedUserId = new EventEmitter<string>();
24+
1825
selectOptionValues = [15, 30, 50, 100, -1];
1926
selectOptionNames = [15, 30, 50, 100, 'All'];
27+
users: User[] = [];
2028
dtOptions: any = {
2129
scrollY: '590px',
2230
dom: '<"d-flex justify-content-between"B<"d-flex"<"mr-5"l>f>>rtip',
@@ -61,14 +69,24 @@ export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewIn
6169
reportDataSource$: Observable<DataSource<Entry>>;
6270
rerenderTableSubscription: Subscription;
6371

64-
constructor(private store: Store<EntryState>) {
72+
constructor(private store: Store<EntryState>, private actionsSubject$: ActionsSubject, private storeUser: Store<User> ) {
6573
this.reportDataSource$ = this.store.pipe(select(getReportDataSource));
6674
}
6775

76+
uploadUsers(): void {
77+
this.storeUser.dispatch(new LoadUsers());
78+
this.actionsSubject$
79+
.pipe(filter((action: any) => action.type === UserActionTypes.LOAD_USERS_SUCCESS))
80+
.subscribe((action) => {
81+
this.users = action.payload;
82+
});
83+
}
84+
6885
ngOnInit(): void {
6986
this.rerenderTableSubscription = this.reportDataSource$.subscribe((ds) => {
7087
this.rerenderDataTable();
7188
});
89+
this.uploadUsers();
7290
}
7391

7492
ngAfterViewInit(): void {
@@ -83,11 +101,11 @@ export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewIn
83101
private rerenderDataTable(): void {
84102
if (this.dtElement && this.dtElement.dtInstance) {
85103
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
86-
dtInstance.destroy();
87-
this.dtTrigger.next();
104+
dtInstance.destroy();
105+
this.dtTrigger.next();
88106
});
89107
} else {
90-
this.dtTrigger.next();
108+
this.dtTrigger.next();
91109
}
92110
}
93111

@@ -100,10 +118,15 @@ export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewIn
100118
return regex.test(uri);
101119
}
102120

103-
bodyExportOptions(data, row, column, node){
121+
bodyExportOptions(data, row, column, node) {
104122
const dataFormated = data.toString().replace(/<((.|\n){0,200}?)>/gi, '');
105123
const durationColumnIndex = 3;
106124
return column === durationColumnIndex ? moment.duration(dataFormated).asHours().toFixed(2) : dataFormated;
107125
}
126+
127+
user(userId: string){
128+
this.selectedUserId.emit(userId);
129+
}
130+
108131
}
109132

src/app/modules/reports/components/time-range-form/time-range-form.component.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ToastrService } from 'ngx-toastr';
22
import { formatDate } from '@angular/common';
3-
import { Component, OnInit } from '@angular/core';
3+
import { SimpleChanges } from '@angular/core';
4+
import { Component, Input, OnInit } from '@angular/core';
45
import { FormControl, FormGroup } from '@angular/forms';
56
import { DATE_FORMAT } from 'src/environments/environment';
67
import * as entryActions from '../../../time-clock/store/entry.actions';
@@ -13,6 +14,9 @@ import * as moment from 'moment';
1314
templateUrl: './time-range-form.component.html',
1415
})
1516
export class TimeRangeFormComponent implements OnInit {
17+
18+
@Input() userId: string;
19+
1620
public reportForm: FormGroup;
1721
private startDate = new FormControl('');
1822
private endDate = new FormControl('');
@@ -27,6 +31,12 @@ export class TimeRangeFormComponent implements OnInit {
2731
this.setInitialDataOnScreen();
2832
}
2933

34+
OnChanges(changes: SimpleChanges){
35+
if (!changes.userId.firstChange){
36+
this.onSubmit();
37+
}
38+
}
39+
3040
setInitialDataOnScreen() {
3141
this.reportForm.setValue({
3242
startDate: formatDate(moment().startOf('week').format('l'), DATE_FORMAT, 'en'),
@@ -43,7 +53,7 @@ export class TimeRangeFormComponent implements OnInit {
4353
this.store.dispatch(new entryActions.LoadEntriesByTimeRange({
4454
start_date: moment(this.startDate.value).startOf('day'),
4555
end_date: moment(this.endDate.value).endOf('day'),
46-
}));
56+
}, this.userId));
4757
}
4858
}
4959
}
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
<app-time-range-form></app-time-range-form>
2-
<app-time-entries-table></app-time-entries-table>
3-
1+
<app-time-range-form [userId]="userId"></app-time-range-form>
2+
<app-time-entries-table (selectedUserId)="user($event)"></app-time-entries-table>
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
import { Component } from '@angular/core';
1+
import { Component, Input } from '@angular/core';
22

33
@Component({
44
selector: 'app-reports',
55
templateUrl: './reports.component.html',
66
styleUrls: ['./reports.component.scss']
77
})
88
export class ReportsComponent {
9+
10+
userId: string;
11+
12+
user(userId: string){
13+
this.userId = userId;
14+
}
915
}
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>Users: </label>
3+
4+
<ng-select [(ngModel)]="selectedUser" placeholder="Select user" (change)="updateUser()" class="selectUser">
5+
<ng-option *ngFor="let user of users" value={{user.id}}>👤{{user.name}}📨{{ user.email}}</ng-option >
6+
</ng-select>
7+
8+
</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@import '../../../../../styles/colors.scss';
2+
3+
label {
4+
width: 225px;
5+
}
6+
.selectUser {
7+
display: inline-block;
8+
width: 350px;
9+
padding: 0 12px 20px 12px;
10+
}
11+
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+
import { UsersService } from 'src/app/modules/users/services/users.service';
3+
@Component({
4+
selector: 'app-search-user',
5+
templateUrl: './search-user.component.html',
6+
styleUrls: ['./search-user.component.scss'],
7+
})
8+
9+
export class SearchUserComponent {
10+
11+
readonly ALLOW_SELECT_MULTIPLE = true;
12+
selectedUser: string;
13+
14+
@Input() users: string[] = [];
15+
16+
@Output() selectedUserId = new EventEmitter<string>();
17+
18+
updateUser() {
19+
this.selectedUserId.emit(this.selectedUser || '*');
20+
}
21+
}
22+

src/app/modules/users/components/users-list/users-list.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class UsersListComponent implements OnInit, OnDestroy, AfterViewInit {
4747
});
4848

4949
this.switchGroupsSubscription = this.filterUserGroup().subscribe((action) => {
50-
this.store.dispatch(new LoadUsers());
50+
this.store.dispatch(new LoadUsers());
5151
});
5252
}
5353

0 commit comments

Comments
 (0)