-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stark-ui): implement toast notification feature
- Loading branch information
Showing
40 changed files
with
1,138 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./common/message"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./message/message.intf"; | ||
export * from "./message/message-type.intf"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* Message types supported by Stark. | ||
*/ | ||
export enum StarkMessageType { | ||
INFO, | ||
WARNING, | ||
ERROR | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { StarkMessageType } from "./message-type.intf"; | ||
|
||
/** | ||
* Simple message with text, type, ... | ||
*/ | ||
export interface StarkMessage { | ||
/** | ||
* Id of the message | ||
*/ | ||
id: string; | ||
|
||
/** | ||
* Translation key of the message to be displayed. If no translation found, it is displayed as is | ||
*/ | ||
key: string; | ||
|
||
/** | ||
* An object containing variable values to interpolate translations against | ||
*/ | ||
interpolateValues?: object; | ||
|
||
/** | ||
* Message code | ||
*/ | ||
code: string; | ||
|
||
/** | ||
* Message type | ||
*/ | ||
type: StarkMessageType; | ||
|
||
/** | ||
* Message priority | ||
* determines the position of a message in a list, the highest priority is shown first | ||
* messages are ordered ascending by priority | ||
* a lower value means a higher priority | ||
* the default value is 999 | ||
*/ | ||
priority?: number; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from "./toast-notification/toast-notification.module"; | ||
export * from "./toast-notification/components"; | ||
export * from "./toast-notification/services"; |
2 changes: 2 additions & 0 deletions
2
packages/stark-ui/src/modules/toast-notification/components.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./components/toast-notification.component"; | ||
export * from "./components/toast-message.intf"; |
13 changes: 13 additions & 0 deletions
13
packages/stark-ui/src/modules/toast-notification/components/_toast-notification-theme.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
.stark-toast { | ||
&.stark-toast-message-error { | ||
background-color: $message-alert-700; | ||
} | ||
|
||
&.stark-toast-message-warning { | ||
background-color: $message-warning-700; | ||
} | ||
|
||
&.stark-toast-message-info { | ||
background-color: $message-info-700; | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...ges/stark-ui/src/modules/toast-notification/components/_toast-notification.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
.mat-snack-bar-container { | ||
margin: 8px !important; | ||
padding: 0 !important; | ||
} | ||
|
||
.stark-toast { | ||
min-height: 0; | ||
display: flex; | ||
white-space: normal; | ||
align-items: center; | ||
padding: 6px 16px 6px 16px; | ||
span { | ||
line-height: 24px; | ||
margin: 6px; | ||
} | ||
mat-icon { | ||
margin: 6px; | ||
min-width: 24px; | ||
width: 24px; | ||
min-height: 24px; | ||
height: 24px; | ||
} | ||
.stark-toast-action { | ||
float: none; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
.stark-toast-text { | ||
flex: 1 1 auto; | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
packages/stark-ui/src/modules/toast-notification/components/toast-message.intf.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { StarkMessage } from "../../../common"; | ||
|
||
/** | ||
* Stark Toast Notification Message Interface | ||
*/ | ||
export interface StarkToastMessage extends StarkMessage { | ||
/** | ||
* How many milliseconds the message will be displayed before automatically closing | ||
* If set to 0, the toast will stay open until closed manually | ||
*/ | ||
delay?: number; | ||
|
||
/** | ||
* If provided, an action button with the label provided will be added in the notification | ||
* The return value is "ok" when this button is clicked | ||
*/ | ||
actionLabel?: string; | ||
|
||
/** | ||
* Array containing the css classes to be applied to the action button (if the message contains an action to be displayed) | ||
*/ | ||
actionClasses?: string[]; | ||
} |
19 changes: 19 additions & 0 deletions
19
...ages/stark-ui/src/modules/toast-notification/components/toast-notification.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<div class="stark-toast" [ngClass]="getMessageTypeClass()"> | ||
|
||
<mat-icon svgIcon="information" starkSvgViewBox *ngIf="message.type === 0"></mat-icon> | ||
<mat-icon svgIcon="alert-circle" starkSvgViewBox *ngIf="message.type === 1"></mat-icon> | ||
<mat-icon svgIcon="alert" starkSvgViewBox *ngIf="message.type === 2"></mat-icon> | ||
|
||
<span class="stark-toast-text" | ||
role="alert" | ||
[innerHTML]="message.key | translate:message.interpolateValues"> | ||
</span> | ||
|
||
<button class="stark-toast-action" | ||
*ngIf="message.actionLabel" | ||
[ngClass]="message.actionClasses" | ||
(click)="closeToast()" | ||
mat-button> | ||
<span translate>{{ message.actionLabel }}</span> | ||
</button> | ||
</div> |
121 changes: 121 additions & 0 deletions
121
...s/stark-ui/src/modules/toast-notification/components/toast-notification.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/*tslint:disable:completed-docs*/ | ||
import { Component, NO_ERRORS_SCHEMA, ViewChild } from "@angular/core"; | ||
import { async, ComponentFixture, TestBed } from "@angular/core/testing"; | ||
import { MAT_SNACK_BAR_DATA, MatSnackBar, MatSnackBarRef } from "@angular/material/snack-bar"; | ||
import { MatButtonModule } from "@angular/material/button"; | ||
import { MatIconModule } from "@angular/material/icon"; | ||
import { TranslateModule } from "@ngx-translate/core"; | ||
import { STARK_LOGGING_SERVICE } from "@nationalbankbelgium/stark-core"; | ||
import { MockStarkLoggingService } from "@nationalbankbelgium/stark-core/testing"; | ||
import { StarkMessageType } from "../../../common"; | ||
import { StarkToastNotificationComponent } from "../components"; | ||
import { StarkSvgViewBoxModule } from "../../svg-view-box"; | ||
|
||
@Component({ | ||
selector: `host-component`, | ||
template: `<stark-toast-notification></stark-toast-notification>` | ||
}) | ||
class TestHostComponent { | ||
@ViewChild(StarkToastNotificationComponent) | ||
public toastNotificationComponent: StarkToastNotificationComponent; | ||
} | ||
|
||
describe("ToastNotificationComponent", () => { | ||
let component: StarkToastNotificationComponent; | ||
let hostComponent: TestHostComponent; | ||
let fixture: ComponentFixture<TestHostComponent>; | ||
|
||
const mockMatSnackBarConfig: any = { | ||
delay: 10, | ||
actionLabel: "action", | ||
actionClasses: [] | ||
}; | ||
|
||
const mockSnackBarRef: Partial<MatSnackBarRef<any>> = { | ||
dismissWithAction: jasmine.createSpy('dismissWithAction') | ||
}; | ||
|
||
const mockSnackBar: Partial<MatSnackBar> = { | ||
_openedSnackBarRef: <MatSnackBarRef<any>>mockSnackBarRef | ||
}; | ||
/** | ||
* async beforeEach | ||
*/ | ||
beforeEach(async(() => { | ||
return ( | ||
TestBed.configureTestingModule({ | ||
declarations: [StarkToastNotificationComponent, TestHostComponent], | ||
imports: [TranslateModule.forRoot(), MatButtonModule, StarkSvgViewBoxModule, MatIconModule], | ||
providers: [ | ||
{ provide: STARK_LOGGING_SERVICE, useValue: new MockStarkLoggingService() }, | ||
{ provide: MatSnackBar, useValue: mockSnackBar }, | ||
{ provide: MAT_SNACK_BAR_DATA, useValue: mockMatSnackBarConfig } | ||
], | ||
schemas: [NO_ERRORS_SCHEMA] // to avoid errors due to "mat-icon" directive not known (which we don't want to add in these tests) | ||
}) | ||
/** | ||
* Compile template and css | ||
*/ | ||
.compileComponents() | ||
); | ||
})); | ||
|
||
/** | ||
* Synchronous beforeEach | ||
*/ | ||
beforeEach(() => { | ||
fixture = TestBed.createComponent(TestHostComponent); | ||
hostComponent = fixture.componentInstance; | ||
fixture.detectChanges(); // trigger initial data binding | ||
|
||
component = hostComponent.toastNotificationComponent; | ||
}); | ||
|
||
describe("on initialization", () => { | ||
it("should set internal component properties", () => { | ||
expect(fixture).toBeDefined(); | ||
expect(component).toBeDefined(); | ||
|
||
expect(component.logger).not.toBeNull(); | ||
expect(component.logger).toBeDefined(); | ||
|
||
expect(component.snackBar).not.toBeNull(); | ||
expect(component.snackBar).toBeDefined(); | ||
|
||
expect(component.data).not.toBeNull(); | ||
expect(component.data).toBeDefined(); | ||
expect(component.data.delay).toBeDefined(); | ||
expect(component.data.delay).toBe(10); | ||
expect(component.data.actionLabel).toBeDefined(); | ||
expect(component.data.actionLabel).toBe("action"); | ||
expect(component.data.actionClasses).toBeDefined(); | ||
expect(component.data.type).toBeUndefined(); | ||
}); | ||
}); | ||
|
||
describe("on closeToast() call", () => { | ||
it("should call hide service method", () => { | ||
component.closeToast(); | ||
if (mockSnackBar._openedSnackBarRef) { expect(mockSnackBar._openedSnackBarRef.dismissWithAction).toHaveBeenCalled(); } | ||
}); | ||
}); | ||
|
||
describe("on getMessageTypeClass() call", () => { | ||
it("should return the correct class name", () => { | ||
let cssClass: string = component.getMessageTypeClass(); | ||
expect(cssClass).toBe(""); | ||
|
||
component.data.type = StarkMessageType.WARNING; | ||
cssClass = component.getMessageTypeClass(); | ||
expect(cssClass).toBe("stark-toast-message-warning"); | ||
|
||
component.data.type = StarkMessageType.INFO; | ||
cssClass = component.getMessageTypeClass(); | ||
expect(cssClass).toBe("stark-toast-message-info"); | ||
|
||
component.data.type = StarkMessageType.ERROR; | ||
cssClass = component.getMessageTypeClass(); | ||
expect(cssClass).toBe("stark-toast-message-error"); | ||
}); | ||
}); | ||
}); |
79 changes: 79 additions & 0 deletions
79
packages/stark-ui/src/modules/toast-notification/components/toast-notification.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { Component, HostBinding, Inject, OnInit, ViewEncapsulation } from "@angular/core"; | ||
import { MAT_SNACK_BAR_DATA, MatSnackBar } from "@angular/material/snack-bar"; | ||
import { STARK_LOGGING_SERVICE, StarkLoggingService } from "@nationalbankbelgium/stark-core"; | ||
import { StarkMessageType } from "../../../common/message"; | ||
import { StarkToastMessage } from "../components"; | ||
|
||
/** | ||
* Name of the component | ||
*/ | ||
const componentName: string = "stark-toast-notification"; | ||
|
||
/** | ||
* Component display stark's toast notification (based on Angular Material's MatSnackBar) with custom html | ||
*/ | ||
@Component({ | ||
selector: "stark-toast-notification", | ||
templateUrl: "./toast-notification.component.html", | ||
encapsulation: ViewEncapsulation.None | ||
}) | ||
export class StarkToastNotificationComponent implements OnInit { | ||
/** | ||
* Adds class="stark-toast-notification" attribute on the host component | ||
*/ | ||
@HostBinding("class") | ||
public class: string = componentName; | ||
|
||
/** | ||
* The message data linked to the toast notification. | ||
*/ | ||
public message: StarkToastMessage; | ||
|
||
/** | ||
* Class constructor | ||
* @param logger - The logger of the application | ||
* @param snackBar - Tha snackBar used to display the toast | ||
* @param data - the data linked to the toast notification | ||
*/ | ||
public constructor( | ||
@Inject(STARK_LOGGING_SERVICE) public logger: StarkLoggingService, | ||
public snackBar: MatSnackBar, | ||
@Inject(MAT_SNACK_BAR_DATA) public data: StarkToastMessage | ||
) { | ||
this.message = data; | ||
this.logger.debug(componentName + ": data received : %o", this.message); | ||
} | ||
|
||
/** | ||
* Component lifecycle hook | ||
*/ | ||
public ngOnInit(): void { | ||
this.logger.debug(componentName + ": controller initialized"); | ||
} | ||
|
||
/** | ||
* Closes the toast | ||
*/ | ||
public closeToast(): void { | ||
// get the reference to the current open toast (this one) from the MatSnackBar service and dismiss it | ||
if (this.snackBar._openedSnackBarRef) { this.snackBar._openedSnackBarRef.dismissWithAction() } | ||
} | ||
|
||
/** | ||
* Generate the css class of the toast notification based on its type | ||
* @returns a string containing the css class of the toast notification | ||
*/ | ||
public getMessageTypeClass(): string { | ||
switch (this.message.type) { | ||
case StarkMessageType.WARNING: | ||
return "stark-toast-message-warning"; | ||
case StarkMessageType.ERROR: | ||
return "stark-toast-message-error"; | ||
case StarkMessageType.INFO: | ||
return "stark-toast-message-info"; | ||
default: | ||
this.logger.error(componentName + ": unknown message type."); | ||
return ""; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from "./services/toast-notification.service.intf"; | ||
export * from "./services/toast-notification.service"; | ||
export * from "./services/toast-notification-result.intf"; | ||
export * from "./services/toast-notification-option.intf"; |
Oops, something went wrong.