Skip to content

Commit c1f523f

Browse files
authored
Tt 344 add pagination where feature is not available (#755)
* fix: TT-343 add pagination in reports tab * fix: TT-344 add horizontal scrolling to handle overflow caused by new datatable format * feat: TT-344 add pagination to time-entries tab * test: TT-344 add test for new methods in time-entries-component * fix: TT-344 fix bug from sonarcloud * fix: TT-344 descending order on time-entries table * fix: TT-344 descending order time-entires table * fix: TT-344 fix bug when modifying/adding/deleting entries * fix: TT-344 handling error from subscription * fix: TT-344 handle pagination bugs * refactor: TT-344 rename test name
1 parent bcc97e7 commit c1f523f

File tree

5 files changed

+106
-76
lines changed

5 files changed

+106
-76
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { getReportDataSource } from '../../../time-clock/store/entry.selectors';
1717
export class TimeEntriesTableComponent implements OnInit, OnDestroy, AfterViewInit {
1818
dtOptions: any = {
1919
scrollY: '590px',
20-
paging: false,
2120
dom: 'Bfrtip',
2221
buttons: [
2322
{

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

Lines changed: 72 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -23,78 +23,82 @@
2323
<app-month-picker [selectedDate]="selectedDate" (dateSelected)="dateSelected($event)"></app-month-picker>
2424
<div style="height: 15px"></div>
2525

26-
<div *ngIf="displayGridView; then gridView; else listView"></div>
27-
<ng-template #gridView>
28-
<div id="gridView">
29-
<div *ngIf="timeEntriesDataSource$ | async as dataSource">
30-
<app-loading-bar *ngIf="dataSource.isLoading"></app-loading-bar>
31-
<app-calendar
32-
*ngIf="!dataSource.isLoading"
33-
[timeEntries$]="timeEntriesDataSource$"
34-
[currentDate]="selectedDate.toDate()"
35-
[calendarView]="calendarView"
36-
(changeDate)="changeDate($event)"
37-
(changeView)="changeView($event)"
38-
(viewModal)="editEntry($event.id)"
39-
(deleteTimeEntry)="openModal($event.timeEntry)"
40-
>
41-
</app-calendar>
42-
</div>
26+
27+
<div id="gridView" [hidden]="!displayGridView">
28+
<div *ngIf="timeEntriesDataSource$ | async as dataSource">
29+
<app-loading-bar *ngIf="dataSource.isLoading"></app-loading-bar>
30+
<app-calendar
31+
*ngIf="!dataSource.isLoading"
32+
[timeEntries$]="timeEntriesDataSource$"
33+
[currentDate]="selectedDate.toDate()"
34+
[calendarView]="calendarView"
35+
(changeDate)="changeDate($event)"
36+
(changeView)="changeView($event)"
37+
(viewModal)="editEntry($event.id)"
38+
(deleteTimeEntry)="openModal($event.timeEntry)"
39+
>
40+
</app-calendar>
4341
</div>
44-
</ng-template>
45-
<ng-template #listView>
46-
<div id="listView">
47-
<table class="table table-sm table-striped mb-0" *ngIf="timeEntriesDataSource$ | async as dataSource">
48-
<thead class="thead-blue">
49-
<tr class="d-flex">
50-
<th class="col">Date</th>
51-
<th class="col">Time in - out</th>
52-
<th class="col">Duration</th>
53-
<th class="col">Customer</th>
54-
<th class="col">Project</th>
55-
<th class="col">Activity</th>
56-
<th class="col"></th>
57-
</tr>
58-
</thead>
59-
<tr *ngIf="dataSource.isLoading">
42+
</div>
43+
44+
<div id="listView" [hidden]="displayGridView">
45+
<table
46+
class="table table-sm table-striped mb-0"
47+
datatable
48+
[dtTrigger]="dtTrigger"
49+
[dtOptions]="dtOptions"
50+
*ngIf="(timeEntriesDataSource$ | async) as dataSource">
51+
<caption></caption>
52+
<thead class="thead-blue">
53+
<tr class="d-flex">
54+
<th class="col">Date</th>
55+
<th class="col">Time in - out</th>
56+
<th class="col">Duration</th>
57+
<th class="col">Customer</th>
58+
<th class="col">Project</th>
59+
<th class="col">Activity</th>
60+
<th class="col"></th>
61+
</tr>
62+
</thead>
63+
<tr *ngIf="dataSource.isLoading">
64+
<td class="text-center" colspan="7">{{NO_DATA_MESSAGE}}</td>
65+
</tr>
66+
<app-loading-bar *ngIf="dataSource.isLoading"></app-loading-bar>
67+
<tbody *ngIf="!dataSource.isLoading">
68+
<tr *ngIf="!dataSource?.data.length">
6069
<td class="text-center" colspan="7">{{NO_DATA_MESSAGE}}</td>
6170
</tr>
62-
<app-loading-bar *ngIf="dataSource.isLoading"></app-loading-bar>
63-
<tbody *ngIf="!dataSource.isLoading">
64-
<tr *ngIf="!dataSource?.data.length">
65-
<td class="text-center" colspan="7">{{NO_DATA_MESSAGE}}</td>
66-
</tr>
67-
<tr class="d-flex" *ngFor="let entry of dataSource.data">
68-
<td class="col">{{ entry.start_date | date: 'MM/dd/yyyy' }}</td>
69-
<td class="col">{{ entry.start_date | date: 'HH:mm' }} - {{ entry.end_date | date: 'HH:mm' }}</td>
70-
<td class="col">{{ entry.end_date | substractDate: entry.start_date }}</td>
71-
<td class="col">{{ entry.customer_name }}</td>
72-
<td class="col">{{ entry.project_name }}</td>
73-
<td class="col">{{ entry.activity_name }}</td>
74-
<td class="col">
75-
<button
76-
class="btn btn-sm btn-primary"
77-
data-toggle="modal"
78-
data-target="#editRecordsByDate"
79-
(click)="editEntry(entry.id)"
80-
>
81-
<i class="fa fa-edit fa-xs"></i>
82-
</button>
83-
<button
84-
class="btn btn-sm btn-danger ml-2"
85-
data-toggle="modal"
86-
data-target="#deleteModal"
87-
(click)="openModal(entry)"
88-
>
89-
<i class="fa fa-trash fa-xs"></i>
90-
</button>
91-
</td>
92-
</tr>
93-
</tbody>
94-
</table>
95-
</div>
96-
</ng-template>
71+
<tr class="d-flex" *ngFor="let entry of dataSource.data">
72+
<td class="col">{{ entry.start_date | date: 'MM/dd/yyyy' }}</td>
73+
<td class="col">{{ entry.start_date | date: 'HH:mm' }} - {{ entry.end_date | date: 'HH:mm' }}</td>
74+
<td class="col">{{ entry.end_date | substractDate: entry.start_date }}</td>
75+
<td class="col">{{ entry.customer_name }}</td>
76+
<td class="col">{{ entry.project_name }}</td>
77+
<td class="col">{{ entry.activity_name }}</td>
78+
<td class="col">
79+
<button
80+
class="btn btn-sm btn-primary"
81+
data-toggle="modal"
82+
data-target="#editRecordsByDate"
83+
(click)="editEntry(entry.id)"
84+
>
85+
<i class="fa fa-edit fa-xs"></i>
86+
</button>
87+
<button
88+
class="btn btn-sm btn-danger ml-2"
89+
data-toggle="modal"
90+
data-target="#deleteModal"
91+
(click)="openModal(entry)"
92+
>
93+
<i class="fa fa-trash fa-xs"></i>
94+
</button>
95+
</td>
96+
</tr>
97+
</tbody>
98+
</table>
99+
</div>
97100
</div>
101+
98102
<div class="modal fade" id="editRecordsByDate" tabindex="-1" role="dialog">
99103
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
100104
<div class="modal-content" cdkDrag (cdkDragEnded)="resetDraggablePosition($event)">

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ describe('TimeEntriesComponent', () => {
133133
});
134134
}));
135135

136+
it('should initialize the table when the component is initialized', () => {
137+
spyOn(component.dtTrigger, 'next');
138+
component.ngAfterViewInit();
139+
140+
expect(component.dtTrigger.next).toHaveBeenCalled();
141+
});
142+
136143
it('when create time entries, the time entries should be queried', () => {
137144
const currentMonth = new Date().getMonth() + 1;
138145
const year = new Date().getFullYear();

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { Component, OnDestroy, OnInit } from '@angular/core';
1+
import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
22
import { ActionsSubject, select, Store } from '@ngrx/store';
3+
import { DataTableDirective } from 'angular-datatables';
34
import { ToastrService } from 'ngx-toastr';
4-
import { Observable, Subscription } from 'rxjs';
5+
import { Observable, Subscription, Subject } from 'rxjs';
56
import { delay, filter } from 'rxjs/operators';
67
import { ProjectSelectedEvent } from '../../shared/components/details-fields/project-selected-event';
78
import { SaveEntryEvent } from '../../shared/components/details-fields/save-entry-event';
@@ -20,7 +21,15 @@ import { CalendarView } from 'angular-calendar';
2021
templateUrl: './time-entries.component.html',
2122
styleUrls: ['./time-entries.component.scss'],
2223
})
23-
export class TimeEntriesComponent implements OnInit, OnDestroy {
24+
export class TimeEntriesComponent implements OnInit, OnDestroy, AfterViewInit {
25+
dtOptions: any = {
26+
order: [[ 0, 'desc' ]],
27+
destroy: true,
28+
};
29+
dtTrigger: Subject<any> = new Subject();
30+
@ViewChild(DataTableDirective, { static: false })
31+
dtElement: DataTableDirective;
32+
rerenderTableSubscription: Subscription;
2433
entryId: string;
2534
entry: Entry;
2635
activeTimeEntry: Entry;
@@ -52,9 +61,7 @@ export class TimeEntriesComponent implements OnInit, OnDestroy {
5261
this.actualDate = new Date();
5362
this.timeEntriesDataSource$ = this.store.pipe(delay(0), select(getTimeEntriesDataSource));
5463
}
55-
ngOnDestroy(): void {
56-
this.entriesSubscription.unsubscribe();
57-
}
64+
5865
ngOnInit(): void {
5966
this.loadActiveEntry();
6067
this.isFeatureToggleCalendarActive = (this.cookiesService.get(FeatureToggle.TIME_TRACKER_CALENDAR) === 'true');
@@ -69,7 +76,20 @@ export class TimeEntriesComponent implements OnInit, OnDestroy {
6976
this.loadActiveEntry();
7077
this.store.dispatch(new entryActions.LoadEntries(this.selectedMonth, this.selectedYear));
7178
});
79+
this.rerenderTableSubscription = this.timeEntriesDataSource$.subscribe((ds) => {
80+
this.dtTrigger.next();
81+
});
82+
}
83+
84+
ngAfterViewInit(): void {
85+
this.dtTrigger.next();
86+
}
87+
88+
ngOnDestroy(): void {
89+
this.rerenderTableSubscription.unsubscribe();
90+
this.entriesSubscription.unsubscribe();
7291
}
92+
7393
newEntry() {
7494
if (this.wasEditingExistingTimeEntry) {
7595
this.entry = null;

src/styles.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ body {
1616
width: 100vw;
1717
margin: 0;
1818
padding: 0;
19-
overflow-x: hidden;
19+
overflow-x: scroll;
2020
overflow-y: hidden;
2121
}
2222

0 commit comments

Comments
 (0)