Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
refactor: #452
Extracting time-entries table source as datasource objects
Removing dead code
Using types on unit tests
Fixing unit tests
  • Loading branch information
Juan Gabriel Guzman committed Jul 28, 2020
commit a2ff91ee18368dd73d65326d3dfcbb6888c49da1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</tr>
</thead>
<app-loading-bar *ngIf="(isLoading$ | async)"></app-loading-bar>
<tbody *ngIf="((isLoading$ | async) === ( false || null || undefined))">
<tbody *ngIf="(isLoading$ | async) === false">
<tr class="d-flex" *ngFor="let activity of activities">
<td class="col-sm-9">{{ activity.name }}</td>
<td class="col-sm-3 text-center">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { OnInit } from '@angular/core';
import { Component } from '@angular/core';
import { Store, select } from '@ngrx/store';

import { LoadActivities, DeleteActivity, SetActivityToEdit } from './../../store/activity-management.actions';
import { ActivityState } from './../../store/activity-management.reducers';
import { allActivities } from '../../store';
import { Activity } from '../../../shared/models';
import { Component, OnInit } from '@angular/core';
import { select, Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { delay } from 'rxjs/operators';
import { getIsLoading } from 'src/app/modules/activities-management/store/activity-management.selectors';
import { Activity } from '../../../shared/models';
import { allActivities } from '../../store';
import { DeleteActivity, LoadActivities, SetActivityToEdit } from './../../store/activity-management.actions';
import { ActivityState } from './../../store/activity-management.reducers';


@Component({
selector: 'app-activity-list',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import { createFeatureSelector, createSelector } from '@ngrx/store';

import { ActivityState } from './activity-management.reducers';

const getActivityState = createFeatureSelector<ActivityState>('activities');

export const allActivities = createSelector(getActivityState, (state: ActivityState) => {
return state.data;
});
export const allActivities = createSelector(getActivityState, (state: ActivityState) => state?.data);

export const activityIdToEdit = createSelector(getActivityState, (state: ActivityState) => {
return state.activityIdToEdit;
});
export const activityIdToEdit = createSelector(getActivityState, (state: ActivityState) => state?.activityIdToEdit);

export const getActivityById = createSelector(allActivities, activityIdToEdit, (activities, activityId) => {
if (activities && activityId) {
Expand All @@ -20,6 +15,4 @@ export const getActivityById = createSelector(allActivities, activityIdToEdit, (
}
});

export const getIsLoading = createSelector(getActivityState, (state: ActivityState) => {
return state.isLoading;
});
export const getIsLoading = createSelector(getActivityState, (state: ActivityState) => state?.isLoading);
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</tr>
</thead>
<app-loading-bar *ngIf="(isLoading$ | async)"></app-loading-bar>
<tbody *ngIf="((isLoading$ | async) === (false || null || undefined))">
<tbody *ngIf="((isLoading$ | async) === false)">
<tr class="d-flex" *ngFor="let customer of customers">
<td class="col-sm-9">{{ customer.name }}</td>
<td class="col-sm-3 text-center">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild, AfterViewInit} from '@angular/core';
import {ActionsSubject, select, Store} from '@ngrx/store';

import {Observable, Subject, Subscription} from 'rxjs';
import { AfterViewInit, Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
import { ActionsSubject, select, Store } from '@ngrx/store';
import { DataTableDirective } from 'angular-datatables';
import { Observable, Subject, Subscription } from 'rxjs';
import { delay, filter } from 'rxjs/operators';
import { getIsLoading } from 'src/app/modules/customer-management/store/customer-management.selectors';
import { Customer } from './../../../../../shared/models/customer.model';
import {
CustomerManagementActionTypes,
DeleteCustomer,
LoadCustomers,
SetCustomerToEdit
} from './../../../../store/customer-management.actions';
import {Customer} from './../../../../../shared/models/customer.model';
import {delay, filter} from 'rxjs/operators';
import {DataTableDirective} from 'angular-datatables';
import { getIsLoading } from 'src/app/modules/customer-management/store/customer-management.selectors';

@Component({
selector: 'app-customer-list',
templateUrl: './customer-list.component.html',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import { createFeatureSelector, createSelector } from '@ngrx/store';

import { ProjectState } from './project.reducer';

const getProjectState = createFeatureSelector<ProjectState>('projects');

export const getCustomerProjects = createSelector(getProjectState, (state: ProjectState) => {
return state;
});
export const getCustomerProjects = createSelector(getProjectState, (state: ProjectState) => state);

export const getProjects = createSelector(getProjectState, (state: ProjectState) => {
return state.projects;
});
export const getProjects = createSelector(getProjectState, (state: ProjectState) => state?.projects);

export const getProjectToEdit = createSelector(getProjectState, (state: ProjectState) => {
return state.projectToEdit;
});
export const getProjectToEdit = createSelector(getProjectState, (state: ProjectState) => state?.projectToEdit);

export const getIsLoading = createSelector(getProjectState, (state: ProjectState) => {
return state.isLoading;
});
export const getIsLoading = createSelector(getProjectState, (state: ProjectState) => state?.isLoading);
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createFeatureSelector, createSelector } from '@ngrx/store';

import { CustomerState } from './customer-management.reducers';

export const getCustomerState = createFeatureSelector<CustomerState>('customers');

export const getStatusMessage = createSelector(getCustomerState, (messageState) => {
Expand Down Expand Up @@ -35,7 +35,6 @@ export const getCustomerUnderEdition = createSelector(allCustomers, customerIdto
}
});


export const getIsLoading = createSelector(getCustomerState, (state: CustomerState) => {
return state.isLoading;
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,53 @@
datatable
[dtTrigger]="dtTrigger"
[dtOptions]="dtOptions"
*ngIf="(reportDataSource$ | async) as dataSource"
>
<thead class="thead-blue">
<tr class="d-flex">
<th class="col md-col">ID</th>
<th class="col md-col">User email</th>
<th class="col sm-col">Date</th>
<th class="col sm-col">Duration (hours)</th>
<th class="col sm-col">Time in</th>
<th class="col sm-col">Time out</th>
<th class="col md-col">Project</th>
<th class="col lg-col">Project ID</th>
<th class="col md-col">Customer</th>
<th class="col lg-col">Customer ID</th>
<th class="col md-col">Activity</th>
<th class="col lg-col">Ticket</th>
<th class="col lg-col">Description</th>
<th class="col lg-col">Technologies</th>
</tr>
<tr class="d-flex">
<th class="col md-col">ID</th>
<th class="col md-col">User email</th>
<th class="col sm-col">Date</th>
<th class="col sm-col">Duration (hours)</th>
<th class="col sm-col">Time in</th>
<th class="col sm-col">Time out</th>
<th class="col md-col">Project</th>
<th class="col lg-col">Project ID</th>
<th class="col md-col">Customer</th>
<th class="col lg-col">Customer ID</th>
<th class="col md-col">Activity</th>
<th class="col lg-col">Ticket</th>
<th class="col lg-col">Description</th>
<th class="col lg-col">Technologies</th>
</tr>
</thead>
<app-loading-bar *ngIf="(isLoading$ | async)"></app-loading-bar>
<tbody *ngIf="(isLoading$ | async) === false ">
<tr
class="d-flex"
*ngFor="let entry of data"
>
<td class="col md-col multiline-col"> {{ entry.id }} </td>
<td class="col md-col multiline-col"> {{ entry.owner_email }} </td>
<td class="col sm-col"> {{ entry.start_date | date: 'MM/dd/yyyy' }} </td>
<td class="col sm-col"> {{ entry.end_date | substractDate: entry.start_date }} </td>
<td class="col sm-col"> {{ entry.start_date | date: 'HH:mm' }} </td>
<td class="col sm-col"> {{ entry.end_date | date: 'HH:mm' }} </td>
<td class="col md-col"> {{ entry.project_name }} </td>
<td class="col md-col"> {{ entry.project_id }} </td>
<td class="col md-col"> {{ entry.customer_name }} </td>
<td class="col md-col"> {{ entry.customer_id }} </td>
<td class="col md-col"> {{ entry.activity_name }} </td>
<td class="col lg-col"> {{ entry.uri }} </td>
<td class="col lg-col multiline-col"> {{ entry.description }} </td>
<td class="col lg-col multiline-col"> {{ entry.technologies }} </td>
</tr>
<app-loading-bar
*ngIf="dataSource.isLoading"
></app-loading-bar>
<tbody *ngIf="!dataSource.isLoading">
<tr
class="d-flex"
*ngFor="let entry of dataSource.data"
>
<td class="col md-col multiline-col">{{ entry.id }}</td>
<td class="col md-col multiline-col">{{ entry.owner_email }}</td>
<td class="col sm-col">
{{ entry.start_date | date: 'MM/dd/yyyy' }}
</td>
<td class="col sm-col">
{{ entry.end_date | substractDate: entry.start_date }}
</td>
<td class="col sm-col">{{ entry.start_date | date: 'HH:mm' }}</td>
<td class="col sm-col">{{ entry.end_date | date: 'HH:mm' }}</td>
<td class="col md-col">{{ entry.project_name }}</td>
<td class="col md-col">{{ entry.project_id }}</td>
<td class="col md-col">{{ entry.customer_name }}</td>
<td class="col md-col">{{ entry.customer_id }}</td>
<td class="col md-col">{{ entry.activity_name }}</td>
<td class="col lg-col">{{ entry.uri }}</td>
<td class="col lg-col multiline-col">{{ entry.description }}</td>
<td class="col lg-col multiline-col">{{ entry.technologies }}</td>
</tr>
</tbody>
</table>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import { AsyncPipe } from '@angular/common';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { Entry } from 'src/app/modules/shared/models';
import { SubstractDatePipe } from 'src/app/modules/shared/pipes/substract-date/substract-date.pipe';
import { getReportDataSource } from 'src/app/modules/time-clock/store/entry.selectors';
import { EntryState } from '../../../time-clock/store/entry.reducer';
import { entriesForReport } from '../../../time-clock/store/entry.selectors';
import { TimeEntriesTableComponent } from './time-entries-table.component';

describe('Reports Page', () => {
describe('TimeEntriesTableComponent', () => {
let component: TimeEntriesTableComponent;
let fixture: ComponentFixture<TimeEntriesTableComponent>;
let store: MockStore<EntryState>;
let geTimeEntriesSelectorMock;
const timeEntry = {
let getReportDataSourceSelectorMock;
const timeEntry: Entry = {
id: '123',
start_date: new Date(),
end_date: new Date(),
activity_id: '123',
technologies: ['react', 'redux'],
comments: 'any comment',
description: 'any comment',
uri: 'custom uri',
project_id: '123'
project_id: '123',
project_name: 'Time-Tracker'
};

const state = {
const state: EntryState = {
active: timeEntry,
isLoading: false,
message: '',
Expand All @@ -42,34 +44,32 @@ describe('Reports Page', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [TimeEntriesTableComponent, AsyncPipe],
providers: [provideMockStore({initialState: state})],
declarations: [TimeEntriesTableComponent, SubstractDatePipe],
providers: [provideMockStore({ initialState: state })],
}).compileComponents();
store = TestBed.inject(MockStore);

}));

beforeEach(() => {
beforeEach(async(() => {
fixture = TestBed.createComponent(TimeEntriesTableComponent);
component = fixture.componentInstance;
fixture.detectChanges();
store.setState(state);
geTimeEntriesSelectorMock = store.overrideSelector(entriesForReport, state.reportDataSource.data);
});
getReportDataSourceSelectorMock = store.overrideSelector(getReportDataSource, state.reportDataSource);
fixture.detectChanges();
}));

it('component should be created', async () => {
expect(component).toBeTruthy();
});

it('on success load time entries, the report should be populated', async () => {
component.ngOnInit();
fixture.detectChanges();

expect(component.data).toEqual(state.reportDataSource.data);
it('on success load time entries, the report should be populated', () => {
component.reportDataSource$.subscribe(ds => {
expect(ds.data).toEqual(state.reportDataSource.data);
});
});

it('after the component is initialized it should initialize the table', async () => {

it('after the component is initialized it should initialize the table', () => {
spyOn(component.dtTrigger, 'next');
component.ngAfterViewInit();

Expand Down
Loading