diff --git a/angular.json b/angular.json
index ce28b0bb4..ed981b32f 100644
--- a/angular.json
+++ b/angular.json
@@ -25,7 +25,8 @@
],
"styles": [
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
- "src/styles.scss"
+ "src/styles.scss",
+ "node_modules/ngx-toastr/toastr.css"
],
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
diff --git a/package-lock.json b/package-lock.json
index bd4ac9221..0b6772138 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "time-tracker",
- "version": "1.1.2",
+ "version": "1.1.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -201,9 +201,9 @@
}
},
"@angular/animations": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.0.5.tgz",
- "integrity": "sha512-WGs4Jxw5sr8GCpxMcwEVuZnDIkdNp9qtmuI2j13v/XAaMjvJ7jssCj9+JG5uI8joCi7PFVAWokPT1DdPwWb13Q=="
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-9.0.7.tgz",
+ "integrity": "sha512-74gY7onajmmnksy5E0/32bFv3B9NuWxV64kqD15YjGrh8AWe1BHt5enQI+rJ2tO8m2DKnwZsctis6k0Kcy+YKQ=="
},
"@angular/cli": {
"version": "9.0.5",
@@ -9386,6 +9386,11 @@
"resolved": "https://registry.npmjs.org/ngx-pagination/-/ngx-pagination-5.0.0.tgz",
"integrity": "sha512-Ur0pTWRe2ZXoJ8impEzo0IZKxY5aEcQfSmL5uBqW1rHI2J6nfzgZAHsSLagKHFGchXq0PkRlDVVMcIaNxYJwvQ=="
},
+ "ngx-toastr": {
+ "version": "12.0.1",
+ "resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-12.0.1.tgz",
+ "integrity": "sha512-PABtbn2dyHweVSbo/py1W3veXzcmZO7uVItfTW9AykSSeAUju3gOCgauAw89km0aJ9EBcPOieaoI+9tAR7Pfug=="
+ },
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
diff --git a/package.json b/package.json
index 7b23b7d34..3a2acb93d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "time-tracker",
- "version": "1.1.2",
+ "version": "1.1.3",
"scripts": {
"ng": "ng",
"start": "ng serve",
@@ -12,7 +12,7 @@
},
"private": true,
"dependencies": {
- "@angular/animations": "~9.0.3",
+ "@angular/animations": "^9.0.7",
"@angular/common": "~9.0.3",
"@angular/compiler": "~9.0.3",
"@angular/core": "~9.0.3",
@@ -29,6 +29,7 @@
"minimist": "^1.2.5",
"msal": "^1.2.1",
"ngx-pagination": "^5.0.0",
+ "ngx-toastr": "^12.0.1",
"rxjs": "~6.5.4",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index b98cec34e..854c9caa7 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -7,4 +7,5 @@ import { Component } from '@angular/core';
})
export class AppComponent {
title = 'time-tracker';
+
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 54b7775eb..66f1389d9 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,3 +1,5 @@
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { ToastrModule } from 'ngx-toastr';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
@@ -54,7 +56,6 @@ import { CreateProjectTypeComponent } from './modules/customer-management/compon
import { CustomerEffects } from './modules/customer-management/store/customer-management.effects';
import { EntryEffects } from './modules/time-clock/store/entry.effects';
import { InjectTokenInterceptor } from './modules/shared/interceptors/inject.token.interceptor';
-import { NotificationComponent } from './modules/shared/components/notification/notification/notification.component';
@NgModule({
declarations: [
@@ -89,11 +90,11 @@ import { NotificationComponent } from './modules/shared/components/notification/
ProjectTypeListComponent,
CreateProjectTypeComponent,
EntryFieldsComponent,
- NotificationComponent,
],
imports: [
CommonModule,
BrowserModule,
+ BrowserAnimationsModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
@@ -116,6 +117,7 @@ import { NotificationComponent } from './modules/shared/components/notification/
ProjectTypeEffects,
EntryEffects,
]),
+ ToastrModule.forRoot()
],
providers: [
{
diff --git a/src/app/modules/activities-management/pages/activities-management.component.html b/src/app/modules/activities-management/pages/activities-management.component.html
index f0b8b20b7..cbcf2ec88 100644
--- a/src/app/modules/activities-management/pages/activities-management.component.html
+++ b/src/app/modules/activities-management/pages/activities-management.component.html
@@ -1,5 +1,4 @@
-
diff --git a/src/app/modules/activities-management/pages/activities-management.component.spec.ts b/src/app/modules/activities-management/pages/activities-management.component.spec.ts
index 55482c917..d20faee04 100644
--- a/src/app/modules/activities-management/pages/activities-management.component.spec.ts
+++ b/src/app/modules/activities-management/pages/activities-management.component.spec.ts
@@ -6,18 +6,28 @@ import { ActivityService } from './../services/activity.service';
import { ActivitiesManagementComponent } from './activities-management.component';
import { ActionsSubject } from '@ngrx/store';
import { ActivityManagementActionTypes } from '../store';
+import { ToastrService, ToastrModule, IndividualConfig } from 'ngx-toastr';
describe('ActivitiesManagementComponent', () => {
let component: ActivitiesManagementComponent;
let fixture: ComponentFixture
;
let activityService: ActivityService;
const activitiesFromApi: Activity[] = [{ id: '123', name: 'aaa', description: 'xxx' }];
+ const toastrService = {
+ success: (message?: string, title?: string, override?: Partial) => { },
+ error: (message?: string, title?: string, override?: Partial) => { }
+ };
+ let injectedToastrService;
beforeEach(async(() => {
const actionSub: ActionsSubject = new ActionsSubject();
TestBed.configureTestingModule({
+ imports: [ToastrModule.forRoot()],
declarations: [ActivitiesManagementComponent],
- providers: [ActivityService, HttpClient, HttpHandler, { provide: ActionsSubject, useValue: actionSub }],
+ providers: [ActivityService, HttpClient, HttpHandler,
+ { provide: ActionsSubject, useValue: actionSub },
+ { provide: ToastrService, useValue: toastrService }
+ ],
}).compileComponents();
}));
@@ -25,7 +35,8 @@ describe('ActivitiesManagementComponent', () => {
fixture = TestBed.createComponent(ActivitiesManagementComponent);
component = fixture.componentInstance;
fixture.detectChanges();
-
+ injectedToastrService = TestBed.inject(ToastrService);
+ console.log(injectedToastrService);
activityService = TestBed.inject(ActivityService);
spyOn(activityService, 'getActivities').and.returnValue(of(activitiesFromApi));
});
@@ -47,9 +58,17 @@ describe('ActivitiesManagementComponent', () => {
});
it('has a succesfull message on CREATE_ACTIVITY_SUCCESS', () => {
+ spyOn(injectedToastrService, 'success');
component.setDataNotification(ActivityManagementActionTypes.CREATE_ACTIVITY_SUCCESS);
- expect(component.notificationMsg).toBe('The activity has been saved successfully.');
+ expect(injectedToastrService.success).toHaveBeenCalled();
+ });
+
+ it('has a succesfull message on UPDATE_ACTIVITY_SUCCESS', () => {
+ spyOn(injectedToastrService, 'success');
+ component.setDataNotification(ActivityManagementActionTypes.UPDATE_ACTIVITY_SUCCESS);
+
+ expect(injectedToastrService.success).toHaveBeenCalled();
});
it('should destroy the subscription', () => {
@@ -62,6 +81,7 @@ describe('ActivitiesManagementComponent', () => {
});
it('#setDataNotification should show an success notification with DELETE_ACTIVITY_SUCCESS case', () => {
+ spyOn(injectedToastrService, 'success').and.returnValue(of(activitiesFromApi));
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
const action = {
type: '[ActivityManagement] DELETE_ACTIVITY_SUCESS',
@@ -69,23 +89,35 @@ describe('ActivitiesManagementComponent', () => {
actionSubject.next(action);
component.setDataNotification(action.type);
- expect(component.showNotification).toBeTrue();
- expect(component.isError).toBeFalse();
+ expect(injectedToastrService.success).toHaveBeenCalled();
});
- it('#setDataNotification should show an error notification with CREATE_ACTIVITY_FAIL case', () => {
- const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
- const action = {
- type: '[ActivityManagement] CREATE_ACTIVITY_FAIL',
- };
- actionSubject.next(action);
+ it('shows an error notification with CREATE_ACTIVITY_FAIL case', () => {
+ spyOn(injectedToastrService, 'error');
- component.setDataNotification(action.type);
- expect(component.showNotification).toBeTrue();
- expect(component.isError).toBeTrue();
+ component.setDataNotification(ActivityManagementActionTypes.CREATE_ACTIVITY_FAIL);
+
+ expect(injectedToastrService.error).toHaveBeenCalled();
+ });
+
+ it('shows an error notification with UPDATE_ACTIVITY_FAIL case', () => {
+ spyOn(injectedToastrService, 'error');
+
+ component.setDataNotification(ActivityManagementActionTypes.UPDATE_ACTIVITY_FAIL);
+
+ expect(injectedToastrService.error).toHaveBeenCalled();
+ });
+
+ it('shows an error notification with DELETE_ACTIVITY_FAIL case', () => {
+ spyOn(injectedToastrService, 'error');
+
+ component.setDataNotification(ActivityManagementActionTypes.DELETE_ACTIVITY_FAIL);
+
+ expect(injectedToastrService.error).toHaveBeenCalled();
});
it('#setDataNotification should not show an error notification with incorrect action', () => {
+ spyOn(injectedToastrService, 'success').and.returnValue(of(activitiesFromApi));
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
const action = {
type: '[ActivityManagement] TEST',
@@ -93,7 +125,5 @@ describe('ActivitiesManagementComponent', () => {
actionSubject.next(action);
component.setDataNotification(action.type);
- expect(component.showNotification).toBeFalse();
- expect(component.isError).toBeFalse();
});
});
diff --git a/src/app/modules/activities-management/pages/activities-management.component.ts b/src/app/modules/activities-management/pages/activities-management.component.ts
index 414c4d13a..c35b4f80e 100644
--- a/src/app/modules/activities-management/pages/activities-management.component.ts
+++ b/src/app/modules/activities-management/pages/activities-management.component.ts
@@ -2,6 +2,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActionsSubject } from '@ngrx/store';
import { Subscription } from 'rxjs';
import { ActivityManagementActionTypes } from '../store';
+import { ToastrService } from 'ngx-toastr';
@Component({
selector: 'app-activities-management',
@@ -9,12 +10,9 @@ import { ActivityManagementActionTypes } from '../store';
styleUrls: ['./activities-management.component.scss'],
})
export class ActivitiesManagementComponent implements OnInit, OnDestroy {
- notificationMsg = '';
- showNotification = false;
- isError = false;
actionsSubscription: Subscription;
- constructor(private actionsSubject$: ActionsSubject) {}
+ constructor(private actionsSubject$: ActionsSubject, private toastrService: ToastrService) {}
ngOnInit() {
this.actionsSubscription = this.actionsSubject$.subscribe((action) => {
@@ -27,26 +25,31 @@ export class ActivitiesManagementComponent implements OnInit, OnDestroy {
}
setDataNotification(action: any) {
- this.showNotification = true;
switch (action) {
case ActivityManagementActionTypes.CREATE_ACTIVITY_SUCCESS: {
- this.notificationMsg = 'The activity has been saved successfully.';
+ this.toastrService.success('The activity has been saved successfully.');
+ break;
+ }
+ case ActivityManagementActionTypes.UPDATE_ACTIVITY_SUCCESS: {
+ this.toastrService.success('The activity has been saved successfully.');
break;
}
case ActivityManagementActionTypes.DELETE_ACTIVITY_SUCCESS: {
- this.notificationMsg = 'The activity has been removed successfully.';
+ this.toastrService.success('The activity has been removed successfully.');
+ break;
+ }
+ case ActivityManagementActionTypes.CREATE_ACTIVITY_FAIL: {
+ this.toastrService.error('An unexpected error happened, please try again later.');
break;
}
- case ActivityManagementActionTypes.CREATE_ACTIVITY_FAIL || ActivityManagementActionTypes.DELETE_ACTIVITY_FAIL: {
- this.notificationMsg = 'An unexpected error happened, please try again later.';
- this.isError = true;
+ case ActivityManagementActionTypes.UPDATE_ACTIVITY_FAIL: {
+ this.toastrService.error('An unexpected error happened, please try again later.');
break;
}
- default: {
- this.showNotification = false;
+ case ActivityManagementActionTypes.DELETE_ACTIVITY_FAIL : {
+ this.toastrService.error('An unexpected error happened, please try again later.');
break;
}
}
- setTimeout(() => ((this.showNotification = false), (this.isError = false)), 3000);
}
}
diff --git a/src/app/modules/customer-management/components/customer-info/components/create-customer/create-customer.html b/src/app/modules/customer-management/components/customer-info/components/create-customer/create-customer.html
index 9e1fb3385..1bdc0d541 100644
--- a/src/app/modules/customer-management/components/customer-info/components/create-customer/create-customer.html
+++ b/src/app/modules/customer-management/components/customer-info/components/create-customer/create-customer.html
@@ -1,16 +1,5 @@