diff --git a/package-lock.json b/package-lock.json
index 5abb2b1c7..a8033c5e0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "time-tracker",
- "version": "1.31.6",
+ "version": "1.31.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -6077,6 +6077,15 @@
"p-try": "^2.0.0"
}
},
+ "serialize-javascript": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
+ "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
"ssri": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz",
@@ -18532,15 +18541,6 @@
}
}
},
- "serialize-javascript": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
- "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
- "dev": true,
- "requires": {
- "randombytes": "^2.1.0"
- }
- },
"serve-index": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
@@ -20015,9 +20015,9 @@
}
},
"serialize-javascript": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
- "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
+ "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
@@ -21250,9 +21250,9 @@
},
"dependencies": {
"serialize-javascript": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
- "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
+ "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
diff --git a/package.json b/package.json
index f5411847c..1ea6a7b0d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "time-tracker",
- "version": "1.31.6",
+ "version": "1.31.7",
"scripts": {
"preinstall": "npx npm-force-resolutions",
"ng": "ng",
diff --git a/src/app/modules/time-entries/pages/time-entries.component.html b/src/app/modules/time-entries/pages/time-entries.component.html
index 8fabce8a2..9df5c7f0a 100644
--- a/src/app/modules/time-entries/pages/time-entries.component.html
+++ b/src/app/modules/time-entries/pages/time-entries.component.html
@@ -22,6 +22,7 @@
Date |
Time in - out |
Duration |
+ Customer |
Project |
Activity |
|
@@ -33,6 +34,7 @@
{{ entry.start_date | date: 'MM/dd/yyyy' }} |
{{ entry.start_date | date: 'HH:mm' }} - {{ entry.end_date | date: 'HH:mm' }} |
{{ entry.end_date | substractDate: entry.start_date }} |
+ {{ entry.customer_name }} |
{{ entry.project_name }} |
{{ entry.activity_name }} |
diff --git a/src/app/modules/time-entries/pages/time-entries.component.spec.ts b/src/app/modules/time-entries/pages/time-entries.component.spec.ts
index 9781720d0..e64fc92f1 100644
--- a/src/app/modules/time-entries/pages/time-entries.component.spec.ts
+++ b/src/app/modules/time-entries/pages/time-entries.component.spec.ts
@@ -18,6 +18,7 @@ import { TimeEntriesComponent } from './time-entries.component';
import { ActionsSubject } from '@ngrx/store';
import { EntryActionTypes } from './../../time-clock/store/entry.actions';
import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';
+import { DebugElement } from '@angular/core';
describe('TimeEntriesComponent', () => {
type Merged = TechnologyState & ProjectState & EntryState;
@@ -57,6 +58,7 @@ describe('TimeEntriesComponent', () => {
project_name: 'Time-tracker',
start_date: new Date('2020-02-05T15:36:15.887Z'),
end_date: new Date('2020-02-05T18:36:15.887Z'),
+ customer_name: 'ioet Inc.',
activity_id: 'development',
technologies: ['Angular', 'TypeScript'],
description: 'No comments',
@@ -375,19 +377,54 @@ describe('TimeEntriesComponent', () => {
component.entry = null;
component.entryId = null;
const lastEntry = {
- description : 'testing is fun',
- technologies : [],
- uri : 'http://testing.is.fun',
- activity_id : 'sss',
- project_id : 'id',
- start_date : new Date(new Date().setHours(0, 0, 0, 0)),
- end_date : new Date(new Date().setHours(0, 0, 0, 0))
+ description: 'testing is fun',
+ technologies: [],
+ uri: 'http://testing.is.fun',
+ activity_id: 'sss',
+ project_id: 'id',
+ start_date: new Date(new Date().setHours(0, 0, 0, 0)),
+ end_date: new Date(new Date().setHours(0, 0, 0, 0))
};
- state.timeEntriesDataSource.data = [ lastEntry ];
+ state.timeEntriesDataSource.data = [lastEntry];
mockEntriesSelector = store.overrideSelector(getTimeEntriesDataSource, state.timeEntriesDataSource);
- component.projectSelected({ projectId : 'id'});
+ component.projectSelected({ projectId: 'id' });
expect(component.entry).toEqual(lastEntry);
}));
+ it('when the data source is loaded, the table should to show the appropriated column titles', waitForAsync(() => {
+ component.timeEntriesDataSource$.subscribe(() => {
+
+ fixture.detectChanges();
+
+ const expectedColumnTitles = [
+ 'Date',
+ 'Time in - out',
+ 'Duration',
+ 'Customer',
+ 'Project',
+ 'Activity',
+ '',
+ ];
+
+ const columnTitles: string[] = [];
+
+ const HTMLTimeEntriesDebugElement: DebugElement = fixture.debugElement;
+ const HTMLTimeEntriesElement: HTMLElement = HTMLTimeEntriesDebugElement.nativeElement;
+ const HTMLTimeEntriesTable = HTMLTimeEntriesElement.querySelector('.table') as HTMLTableElement;
+ const HTMLTableHead = HTMLTimeEntriesTable.rows[0];
+
+ Array.from(HTMLTableHead.cells).forEach(columnTitle => {
+ columnTitles.push(columnTitle.innerText);
+ });
+ expect(expectedColumnTitles).toEqual(columnTitles);
+ });
+ }));
+
+ it('when the data source is loaded, the entry should to have customer_name field', waitForAsync(() => {
+ component.timeEntriesDataSource$.subscribe(dataSource => {
+ const entryData = dataSource.data[0];
+ expect(entryData.customer_name).toContain('ioet Inc.');
+ });
+ }));
});
diff --git a/src/app/modules/users/components/users-list/users-list.component.html b/src/app/modules/users/components/users-list/users-list.component.html
index 71aa110da..b13c0206f 100644
--- a/src/app/modules/users/components/users-list/users-list.component.html
+++ b/src/app/modules/users/components/users-list/users-list.component.html
@@ -1,22 +1,23 @@
- User Email |
- Names |
- Roles |
+ User Email |
+ Names |
+ Roles |
-
+
- {{ user.email }} |
- {{ user.name }} |
-
+ | {{ user.email }} |
+ {{ user.name }} |
+
{
let component: UsersListComponent;
let fixture: ComponentFixture;
let store: MockStore;
- let featureManagerService: FeatureManagerService;
const actionSub: ActionsSubject = new ActionsSubject();
const state: UserState = {
@@ -39,7 +36,6 @@ describe('UsersListComponent', () => {
declarations: [UsersListComponent],
providers: [provideMockStore({ initialState: state }), { provide: ActionsSubject, useValue: actionSub }],
}).compileComponents();
- featureManagerService = TestBed.inject(FeatureManagerService);
})
);
@@ -75,36 +71,6 @@ describe('UsersListComponent', () => {
expect(component.users).toEqual(state.data);
});
- it('When Component is created, should call the feature toggle method', () => {
- spyOn(component, 'isFeatureToggleActivated').and.returnValue(of(true));
-
- component.ngOnInit();
-
- expect(component.isFeatureToggleActivated).toHaveBeenCalled();
- expect(component.isUserRoleToggleOn).toBe(true);
- });
-
- const actionsParams = [
- { actionType: UserActionTypes.GRANT_USER_ROLE_SUCCESS },
- { actionType: UserActionTypes.REVOKE_USER_ROLE_SUCCESS },
- ];
-
- actionsParams.map((param) => {
- it(`When action ${param.actionType} is dispatched should triggered load Users action`, () => {
- spyOn(store, 'dispatch');
-
- const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
- const action = {
- type: param.actionType,
- payload: state.data,
- };
-
- actionSubject.next(action);
-
- expect(store.dispatch).toHaveBeenCalledWith(new LoadUsers());
- });
- });
-
const grantRoleTypes = [
{ roleId: 'admin', roleValue: 'time-tracker-admin' },
{ roleId: 'test', roleValue: 'time-tracker-tester' },
@@ -190,23 +156,7 @@ describe('UsersListComponent', () => {
});
});
- const toggleValues = [true, false];
- toggleValues.map((toggleValue) => {
- it(`when FeatureToggle is ${toggleValue} should return ${toggleValue}`, () => {
- spyOn(featureManagerService, 'isToggleEnabledForUser').and.returnValue(of(toggleValue));
-
- const isFeatureToggleActivated: Observable = component.isFeatureToggleActivated();
-
- expect(featureManagerService.isToggleEnabledForUser).toHaveBeenCalled();
- isFeatureToggleActivated.subscribe((value) => expect(value).toEqual(toggleValue));
- });
- });
-
- /*
- TODO: block commented on purpose so that when the tests pass and the Feature toggle is removed,
- the table will be rendered again with dtInstance and not with dtOptions
-
- it('on success load users, the datatable should be reloaded', async () => {
+ it('on success load users, the datatable should be reloaded', async () => {
const actionSubject = TestBed.inject(ActionsSubject);
const action = {
type: UserActionTypes.LOAD_USERS_SUCCESS,
@@ -217,7 +167,7 @@ describe('UsersListComponent', () => {
actionSubject.next(action);
expect(component.dtElement.dtInstance.then).toHaveBeenCalled();
- });*/
+ });
afterEach(() => {
component.dtTrigger.unsubscribe();
diff --git a/src/app/modules/users/components/users-list/users-list.component.ts b/src/app/modules/users/components/users-list/users-list.component.ts
index 91cfc2e23..bf4df91c4 100644
--- a/src/app/modules/users/components/users-list/users-list.component.ts
+++ b/src/app/modules/users/components/users-list/users-list.component.ts
@@ -2,11 +2,10 @@ import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular
import { ActionsSubject, select, Store } from '@ngrx/store';
import { DataTableDirective } from 'angular-datatables';
import { Observable, Subject, Subscription } from 'rxjs';
-import { delay, filter, map } from 'rxjs/operators';
+import { delay, filter } from 'rxjs/operators';
import { User } from '../../models/users';
import { GrantRoleUser, LoadUsers, RevokeRoleUser, UserActionTypes } from '../../store/user.actions';
import { getIsLoading } from '../../store/user.selectors';
-import { FeatureManagerService } from 'src/app/modules/shared/feature-toggles/feature-toggle-manager.service';
@Component({
selector: 'app-users-list',
@@ -22,20 +21,12 @@ export class UsersListComponent implements OnInit, OnDestroy, AfterViewInit {
@ViewChild(DataTableDirective, { static: false })
dtElement: DataTableDirective;
dtOptions: any = {};
- isUserRoleToggleOn;
- constructor(
- private store: Store,
- private actionsSubject$: ActionsSubject,
- private featureManagerService: FeatureManagerService
- ) {
+ constructor(private store: Store, private actionsSubject$: ActionsSubject) {
this.isLoading$ = store.pipe(delay(0), select(getIsLoading));
}
ngOnInit(): void {
- this.isFeatureToggleActivated().subscribe((flag) => {
- this.isUserRoleToggleOn = flag;
- });
this.store.dispatch(new LoadUsers());
this.loadUsersSubscription = this.actionsSubject$
.pipe(filter((action: any) => action.type === UserActionTypes.LOAD_USERS_SUCCESS))
@@ -43,19 +34,6 @@ export class UsersListComponent implements OnInit, OnDestroy, AfterViewInit {
this.users = action.payload;
this.rerenderDataTable();
});
-
- this.switchRoleSubscription = this.actionsSubject$
- .pipe(
- filter(
- (action: any) =>
- action.type === UserActionTypes.GRANT_USER_ROLE_SUCCESS ||
- action.type === UserActionTypes.REVOKE_USER_ROLE_SUCCESS
- )
- )
- .subscribe((action) => {
- this.store.dispatch(new LoadUsers());
- this.rerenderDataTable();
- });
}
ngAfterViewInit(): void {
@@ -83,12 +61,4 @@ export class UsersListComponent implements OnInit, OnDestroy, AfterViewInit {
? this.store.dispatch(new RevokeRoleUser(userId, roleId))
: this.store.dispatch(new GrantRoleUser(userId, roleId));
}
-
- isFeatureToggleActivated() {
- return this.featureManagerService.isToggleEnabledForUser('ui-list-test-users').pipe(
- map((enabled) => {
- return enabled === true ? true : false;
- })
- );
- }
}
| |