Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

383 notification service (#736) #745

Merged
merged 27 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2e6ff6a
383 notification service (#736)
lucasrasec Jul 12, 2023
432faba
Delete yarn.lock
AlyssonMascarenhas Jul 12, 2023
6498c29
Revert "Delete yarn.lock"
alysson-mascarenhas-brisa Jul 12, 2023
bd43298
chore: remove trim of yarn.lock
alysson-mascarenhas-brisa Jul 12, 2023
76a604c
Merge branch 'main' into ion-notification-service
iurynogueira Jul 14, 2023
03a28ca
Merge branch 'main' into ion-notification-service
AlyssonMascarenhas Jul 26, 2023
c401ed9
fix: fixing tests
AlyssonMascarenhas Jul 26, 2023
9876199
Merge branch 'main' into ion-notification-service
iurynogueira Jul 31, 2023
a335b1b
refactor: updating notification service ts and spec #383
Aug 2, 2023
b2907e9
Merge branch 'main' into ion-notification-service
iurynogueira Aug 4, 2023
d09d963
refactor: changes pointed on review #383
Aug 4, 2023
613ee44
Merge branch 'ion-notification-service' of https://github.com/Brisane…
Aug 4, 2023
a5997e1
Merge branch 'main' into ion-notification-service
lucas-alcantara-brisa Aug 4, 2023
3053286
Merge branch 'main' of https://github.com/Brisanet/ion into ion-notif…
Aug 4, 2023
94f1aca
Merge branch 'ion-notification-service' of https://github.com/Brisane…
Aug 4, 2023
90c50d8
Merge branch 'main' of https://github.com/Brisanet/ion into ion-notif…
Aug 7, 2023
f3a7bcd
refactor: adding test to complete coverage #383
Aug 7, 2023
7bd553d
Merge branch 'main' into ion-notification-service
AlyssonMascarenhas Aug 9, 2023
37bcb29
fix: lint fix
AlyssonMascarenhas Aug 9, 2023
907c77e
Merge branch 'main' into ion-notification-service
iurynogueira Aug 24, 2023
368e431
Merge branch 'main' into ion-notification-service
iurynogueira Aug 31, 2023
b0d20d3
Merge branch 'main' into ion-notification-service
iurynogueira Sep 4, 2023
001bf12
Merge branch 'main' into ion-notification-service
iurynogueira Sep 11, 2023
9feba7f
refactor: review changes, refactoring ts file and new test case #383
Sep 12, 2023
e1a94b9
Merge branch 'main' into ion-notification-service
iurynogueira Sep 14, 2023
afee841
Merge branch 'main' into ion-notification-service
iurynogueira Sep 19, 2023
dc17077
Merge branch 'main' into ion-notification-service
iurynogueira Sep 19, 2023
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
5 changes: 4 additions & 1 deletion projects/ion/src/lib/core/types/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { fadeInDirection, fadeOutDirection } from '../../utils/animationsTypes';
import { IconType } from './icon';
import { StatusType } from './status';

export interface NotificationProps {
export interface NotificationProps extends NotificationConfigOptions {
title: string;
message: string;
type?: StatusType;
}

export interface NotificationConfigOptions {
icon?: IconType;
fixed?: boolean;
fadeIn?: fadeInDirection;
Expand Down
2 changes: 1 addition & 1 deletion projects/ion/src/lib/icon/mock/list-icons.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
import { IonIconComponent } from '../icon.component';
import { IonInputComponent } from '../../input/input.component';
import { FormsModule } from '@angular/forms';
import { IonNotificationComponent } from '../../notification/notification.component';
import { IonNotificationComponent } from '../../notification/component/notification.component';

@NgModule({
declarations: [IonInputComponent, IonIconComponent, IonNotificationComponent],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import '../../styles/index.scss';
@import '../utils/fadeAnimations.scss';
@import '../../../styles/index.scss';
@import '../../utils/fadeAnimations.scss';

@mixin icon-color($color) {
::ng-deep svg {
Expand All @@ -13,9 +13,11 @@
align-items: flex-start;
justify-content: space-between;
padding: spacing(1.5) spacing(2);

position: relative;
z-index: $zIndexMax;
max-width: 500px;
min-width: 250px;

background: rgba(255, 255, 255, 0.9);
box-shadow: 0px 8px 6px -4px rgba(0, 0, 0, 0.15),
Expand Down Expand Up @@ -75,3 +77,11 @@
.negative-icon {
@include icon-color($negative-color);
}

.notification-container:nth-child(2) {
top: 30px;
}

.notification-container:nth-child(3) {
top: 30px;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { EventEmitter } from '@angular/core';
import { fireEvent, render, screen } from '@testing-library/angular';
import { StatusType } from '../core/types';
import { NotificationProps } from '../core/types/notification';
import { IonIconModule } from '../icon/icon.module';
import { StatusType } from '../../core/types';
import { NotificationProps } from '../../core/types/notification';
import { IonIconModule } from '../../icon/icon.module';
import { IonNotificationComponent } from './notification.component';

const defaultNotification = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
ViewChild,
} from '@angular/core';
import { Subscription } from 'rxjs';
import { IconType } from '../core/types/icon';
import { NotificationProps } from '../core/types/notification';
import { setTimer } from '../utils/setTimer';
import { IconType } from '../../core/types/icon';
import { NotificationProps } from '../../core/types/notification';
import { setTimer } from '../../utils/setTimer';

@Component({
selector: 'ion-notification',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { IonNotificationService } from './../service/notification.service';
import { Component } from '@angular/core';

@Component({
selector: 'open-notification-button',
template: `
<div style="display: flex; flex-direction: column; gap: 2rem;">
<ion-button
class="button"
label="success"
iconType="check"
(ionOnClick)="notificationSuccess()"
></ion-button>

<ion-button
class="button"
label="warning"
type="dashed"
iconType="exclamation"
(ionOnClick)="notificationWarning()"
></ion-button>

<ion-button
class="button"
label="info"
type="secondary"
iconType="info"
(ionOnClick)="notificationInfo()"
></ion-button>

<ion-button
class="button"
label="error"
[danger]="true"
iconType="close"
(ionOnClick)="notificationError()"
></ion-button>
<div></div>
</div>
`,
styles: [
`
.button {
/deep/ button {
width: 150px !important;
}
}
`,
],
})
export class OpenNotificationButtonComponent {
constructor(private ionNotificationService: IonNotificationService) {}

notificationSuccess(): void {
this.ionNotificationService.success(
'Title...',
'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
);
}

notificationWarning(): void {
this.ionNotificationService.warning(
'Title...',
'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
);
}

notificationInfo(): void {
this.ionNotificationService.info(
'Title...',
'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
);
}

notificationError(): void {
this.ionNotificationService.error(
'Title...',
'Lorem ipsum dolor sit amet, consectetur adipiscing elit...'
);
}
}
13 changes: 10 additions & 3 deletions projects/ion/src/lib/notification/notification.module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { IonNotificationContainerComponent } from './service/notification.container.component';
import { IonNotificationService } from './service/notification.service';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonIconModule } from '../icon/icon.module';
import { IonNotificationComponent } from './notification.component';
import { IonNotificationComponent } from './component/notification.component';

@NgModule({
declarations: [IonNotificationComponent],
declarations: [IonNotificationComponent, IonNotificationContainerComponent],
imports: [CommonModule, IonIconModule],
exports: [IonNotificationComponent],
providers: [IonNotificationService],
exports: [IonNotificationComponent, IonNotificationContainerComponent],
entryComponents: [
IonNotificationComponent,
IonNotificationContainerComponent,
],
})
export class IonNotificationModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { IonNotificationComponent } from '../component/notification.component';
import { Component, ComponentRef, Renderer2, ElementRef } from '@angular/core';

@Component({
selector: 'notification-container',
template: '',
styleUrls: ['notification.container.scss'],
})
export class IonNotificationContainerComponent {
constructor(private renderer: Renderer2, private element: ElementRef) {}

addNotification(notification: ComponentRef<IonNotificationComponent>): void {
notification.instance.ionOnClose.subscribe(() => {
this.removeNotification(notification.location.nativeElement);
});

this.renderer.appendChild(
this.element.nativeElement,
notification.location.nativeElement
);
}

removeNotification(notification: ElementRef): void {
this.renderer.removeChild(this.element.nativeElement, notification);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
:host {
position: absolute;
display: flex;
flex-direction: column;
top: 0;
right: 0;
gap: 1rem;
}
126 changes: 126 additions & 0 deletions projects/ion/src/lib/notification/service/notification.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { IonSharedModule } from './../../shared.module';
import { IonNotificationContainerComponent } from './notification.container.component';
import { IonNotificationComponent } from '../component/notification.component';
import { IonNotificationService } from './notification.service';
import { TestBed } from '@angular/core/testing';
import { Component, NgModule } from '@angular/core';
import { fireEvent, screen } from '@testing-library/angular';

const NOTIFICATION_ICONS = {
success: 'success-icon',
info: 'info-icon',
warning: 'warning-icon',
negative: 'negative-icon',
};

const NOTIFICATION_TYPES = ['success', 'info', 'warning', 'negative'];
lucas-alcantara-brisa marked this conversation as resolved.
Show resolved Hide resolved

@Component({
template: '<div></div>',
})
class ContainerRefTestComponent {}

@NgModule({
declarations: [
ContainerRefTestComponent,
IonNotificationContainerComponent,
IonNotificationComponent,
],
imports: [IonSharedModule],
entryComponents: [
ContainerRefTestComponent,
IonNotificationContainerComponent,
IonNotificationComponent,
],
})
class TestModule {}

jest.setTimeout(1000);

describe('NotificationService', () => {
let notificationService: IonNotificationService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TestModule],
}).compileComponents();

notificationService = TestBed.get(IonNotificationService);
});

it('should remove a notification', () => {
notificationService.success('Custom', 'Custom', { fixed: true });
const removeNotification = screen.getByTestId('btn-remove');
fireEvent.click(removeNotification);
const elements = document.getElementsByTagName('ion-notification');
expect(elements).toHaveLength(0);
});

it('should remove a notification', () => {
lucas-alcantara-brisa marked this conversation as resolved.
Show resolved Hide resolved
const closeEvent = jest.fn();
notificationService.success(
'Custom',
'Custom',
{ fixed: true },
closeEvent
);
const removeNotification = screen.getByTestId('btn-remove');
fireEvent.click(removeNotification);
expect(closeEvent).toHaveBeenCalledTimes(1);
});

it('should create a notification', () => {
lucas-alcantara-brisa marked this conversation as resolved.
Show resolved Hide resolved
notificationService.success('Teste', 'Teste');
expect(screen.getByTestId('ion-notification')).toBeTruthy();
});
});

describe('NotificationService -> notification types', () => {
let notificationService: IonNotificationService;

let currentIndex = 1;

let notificationsOnScreen = 5;

const indexToRemove = [1, 2, 0];

const NOTIFICATIONS_CALLS = {
success: (): void => {
notificationService.success('teste', 'teste');
},
info: (): void => {
notificationService.info('teste', 'teste');
},
warning: (): void => {
notificationService.warning('teste', 'teste');
},
negative: (): void => {
notificationService.error('teste', 'teste');
},
};

beforeEach(() => {
TestBed.configureTestingModule({
imports: [TestModule],
}).compileComponents();

notificationService = TestBed.get(IonNotificationService);
});

it.each(NOTIFICATION_TYPES)('should create %s notification', async (type) => {
NOTIFICATIONS_CALLS[type]();
const iconType = screen.getAllByTestId('notification-icon');
expect(iconType[currentIndex]).toHaveClass(NOTIFICATION_ICONS[type]);
currentIndex += 1;
});
lucas-alcantara-brisa marked this conversation as resolved.
Show resolved Hide resolved

it.each(indexToRemove)(
'should remove multiple notifications',
async (index) => {
const elements = document.getElementsByTagName('ion-notification');
const removeNotification = screen.getAllByTestId('btn-remove');
fireEvent.click(removeNotification[index]);
notificationsOnScreen -= 1;
expect(elements).toHaveLength(notificationsOnScreen);
}
);
});
Loading