{
diff --git a/src/app/modules/time-clock/store/entry.effects.ts b/src/app/modules/time-clock/store/entry.effects.ts
index 40c1cb1c9..f9fc9d769 100644
--- a/src/app/modules/time-clock/store/entry.effects.ts
+++ b/src/app/modules/time-clock/store/entry.effects.ts
@@ -45,6 +45,9 @@ export class EntryEffects {
mergeMap(() =>
this.entryService.summary().pipe(
map((response) => {
+ if (!response){
+ this.toastrService.warning('Your summary information could not be loaded');
+ }
return new actions.LoadEntriesSummarySuccess(response);
}),
catchError((error) => {
diff --git a/src/app/modules/time-clock/store/entry.reducer.ts b/src/app/modules/time-clock/store/entry.reducer.ts
index d3af715f8..023328efb 100644
--- a/src/app/modules/time-clock/store/entry.reducer.ts
+++ b/src/app/modules/time-clock/store/entry.reducer.ts
@@ -266,7 +266,7 @@ export const entryReducer = (state: EntryState = initialState, action: EntryActi
return {
...state,
isLoading: true,
- resultSumEntriesSelected:{hours:0, minutes:0, seconds:0},
+ resultSumEntriesSelected: {hours: 0, minutes: 0, seconds: 0},
reportDataSource: {
data: [],
isLoading: true
diff --git a/src/app/modules/time-clock/store/entry.selectors.spec.ts b/src/app/modules/time-clock/store/entry.selectors.spec.ts
index 06c3c02e2..1d5c088c0 100644
--- a/src/app/modules/time-clock/store/entry.selectors.spec.ts
+++ b/src/app/modules/time-clock/store/entry.selectors.spec.ts
@@ -55,7 +55,7 @@ describe('Entry selectors', () => {
});
it('should select resultSumEntriesSelected', () => {
- const resultSumEntriesSelected:TotalHours = { hours:0, minutes:0, seconds:0 };
+ const resultSumEntriesSelected: TotalHours = { hours: 0, minutes: 0, seconds: 0 };
const entryState = { resultSumEntriesSelected };
expect(selectors.getResultSumEntriesSelected.projector(entryState)).toEqual(resultSumEntriesSelected);
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 87f2da3c6..ce4b96f74 100644
--- a/src/app/modules/time-entries/pages/time-entries.component.html
+++ b/src/app/modules/time-entries/pages/time-entries.component.html
@@ -33,7 +33,7 @@
Customer |
Project |
Activity |
- |
+ Actions |
@@ -45,13 +45,13 @@
{{ entry.customer_name }} |
{{ entry.project_name }} |
{{ entry.activity_name }} |
-
+ |
+
+
+
+
|
diff --git a/src/app/modules/time-entries/pages/time-entries.component.scss b/src/app/modules/time-entries/pages/time-entries.component.scss
index f8d73e904..5cbc63b85 100644
--- a/src/app/modules/time-entries/pages/time-entries.component.scss
+++ b/src/app/modules/time-entries/pages/time-entries.component.scss
@@ -26,3 +26,7 @@ table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc {
background-image: none;
}
+
+.actions-buttons {
+ text-align: center;
+}
diff --git a/src/app/modules/user/services/user-info.service.spec.ts b/src/app/modules/user/services/user-info.service.spec.ts
index 79d2ef782..04f17c586 100644
--- a/src/app/modules/user/services/user-info.service.spec.ts
+++ b/src/app/modules/user/services/user-info.service.spec.ts
@@ -75,4 +75,13 @@ describe('UserInfoService', () => {
});
});
+ it('should return true if is Admin and isLegacyProduction', () => {
+ const groupsTT = {groups: ['fake-admin', 'fake-admin-tt']};
+ spyOn(mockLoginService, 'getLocalStorage').and.returnValue(JSON.stringify(groupsTT));
+ service.isLegacyProduction = true;
+ service.isMemberOf('fake-admin').subscribe((value) => {
+ expect(value).toEqual(true);
+ });
+ });
+
});
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 ecc05e543..ff18560c2 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
@@ -20,6 +20,7 @@
admin
diff --git a/src/app/modules/users/components/users-list/users-list.component.spec.ts b/src/app/modules/users/components/users-list/users-list.component.spec.ts
index 025d5b1d9..ada0b01ef 100644
--- a/src/app/modules/users/components/users-list/users-list.component.spec.ts
+++ b/src/app/modules/users/components/users-list/users-list.component.spec.ts
@@ -1,4 +1,5 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { NgxPaginationModule } from 'ngx-pagination';
import { UsersListComponent } from './users-list.component';
@@ -7,12 +8,22 @@ import { ActionsSubject } from '@ngrx/store';
import { DataTablesModule } from 'angular-datatables';
import { GrantUserRole, RevokeUserRole } from '../../store/user.actions';
import { ROLES } from '../../../../../environments/environment';
+import { LoginService } from '../../../login/services/login.service';
+import { of } from 'rxjs';
+import { UserInfoService } from 'src/app/modules/user/services/user-info.service';
+
describe('UsersListComponent', () => {
let component: UsersListComponent;
let fixture: ComponentFixture;
let store: MockStore;
+ let httpMock: HttpTestingController;
const actionSub: ActionsSubject = new ActionsSubject();
+ let loginService: LoginService;
+ let userInfoService: UserInfoService;
+ const userInfoServiceStub = {
+ isAdmin: () => of(false),
+ };
const state: UserState = {
data: [
@@ -33,9 +44,11 @@ describe('UsersListComponent', () => {
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
- imports: [NgxPaginationModule, DataTablesModule],
+ imports: [NgxPaginationModule, DataTablesModule, HttpClientTestingModule],
declarations: [UsersListComponent],
- providers: [provideMockStore({ initialState: state }), { provide: ActionsSubject, useValue: actionSub }],
+ providers: [provideMockStore({ initialState: state }),
+ { provide: ActionsSubject, useValue: actionSub },
+ { providers: LoginService, useValue: {} }, ],
}).compileComponents();
})
);
@@ -44,6 +57,9 @@ describe('UsersListComponent', () => {
fixture = TestBed.createComponent(UsersListComponent);
component = fixture.componentInstance;
store = TestBed.inject(MockStore);
+ httpMock = TestBed.inject(HttpTestingController);
+ loginService = TestBed.inject(LoginService);
+ userInfoService = TestBed.inject(UserInfoService);
store.setState(state);
fixture.detectChanges();
});
@@ -229,6 +245,16 @@ describe('UsersListComponent', () => {
expect(component.ROLES).toEqual(ROLES);
});
+ it('Should call to localstorage and helper decode for get information about user when checkRoleCurrentUser method is called', () => {
+ const account = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFiYyIsIm5hbWUiOiJhYmMiLCJlbWFpbCI6ImVtYWlsIiwiZ3JvdXBzIjpbImFkbWluIl19.gy1GljkoiuOjP8DzkoLRYE9SldBn5ljRc4kp8rwq7UI';
+ spyOn(loginService, 'getLocalStorage').and.returnValue(account);
+ spyOn(userInfoService, 'isAdmin').and.returnValue(of(true));
+ const response = component.checkRoleCurrentUser('email');
+ expect(response).toBeTrue();
+ expect(userInfoService.isAdmin).toHaveBeenCalled();
+ expect(loginService.getLocalStorage).toHaveBeenCalled();
+ });
+
afterEach(() => {
component.dtTrigger.unsubscribe();
component.loadUsersSubscription.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 6145e5d5a..d973a25f3 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
@@ -9,6 +9,9 @@ import { EnvironmentType } from 'src/environments/enum';
import { User } from '../../models/users';
import { LoadUsers, UserActionTypes, AddUserToGroup, RemoveUserFromGroup } from '../../store/user.actions';
import { getIsLoading } from '../../store/user.selectors';
+import { UserInfoService } from 'src/app/modules/user/services/user-info.service';
+import { LoginService } from '../../../login/services/login.service';
+import { JwtHelperService } from '@auth0/angular-jwt';
@Component({
selector: 'app-users-list',
@@ -28,13 +31,16 @@ export class UsersListComponent implements OnInit, OnDestroy, AfterViewInit {
};
switchGroupsSubscription: Subscription;
isDevelopmentOrProd = true;
+ helper: JwtHelperService;
public get ROLES() {
return ROLES;
}
- constructor(private store: Store, private actionsSubject$: ActionsSubject) {
+ constructor(private store: Store, private actionsSubject$: ActionsSubject,
+ private userInfoService: UserInfoService, private loginService: LoginService) {
this.isLoading$ = store.pipe(delay(0), select(getIsLoading));
+ this.helper = new JwtHelperService();
}
ngOnInit(): void {
@@ -94,4 +100,11 @@ export class UsersListComponent implements OnInit, OnDestroy, AfterViewInit {
)
);
}
+
+ checkRoleCurrentUser(userEmail: string){
+ const token = this.loginService.getLocalStorage('user');
+ const user = this.helper.decodeToken(token);
+ return this.userInfoService.isAdmin() && (userEmail === user.email);
+ }
+
}
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index 7e836342b..f5e34a552 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -3,22 +3,23 @@
// The list of file replacements can be found in 'angular.json'.
import { EnvironmentType } from './enum';
+/* tslint:disable:no-string-literal */
export const environment = {
production: EnvironmentType.TT_DEV,
timeTrackerApiUrl: process.env['API_URL'],
stackexchangeApiUrl: 'https://api.stackexchange.com',
};
-
-
export const AUTHORITY = process.env['AUTHORITY'];
export const CLIENT_ID = process.env['CLIENT_ID'];
export const CLIENT_URL = process.env['CLIENT_URL'];
export const SCOPES = process.env['SCOPES'].split(',');
-export const ITEMS_PER_PAGE = 5;
export const STACK_EXCHANGE_ID = process.env['STACK_EXCHANGE_ID'];
export const STACK_EXCHANGE_ACCESS_TOKEN = process.env['STACK_EXCHANGE_ACCESS_TOKEN'];
export const AZURE_APP_CONFIGURATION_CONNECTION_STRING = process.env['AZURE_APP_CONFIGURATION_CONNECTION_STRING'];
+/* tslint:enable:no-string-literal */
+export const ITEMS_PER_PAGE = 5;
+
export const DATE_FORMAT = 'yyyy-MM-dd';
export const DATE_FORMAT_YEAR = 'YYYY-MM-DD';
export const GROUPS = {
|