mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[HXCS-1166] extend SnackBar to customize content appearance (#8379)
* [HXCS-1166] add templateRef to SnackBarData interface * [HXCS-1166] update SnackBarContentComponent to be able to manage data.templateRef * [HXCS-1166] add tests to NotificationService * [HXCS-1166] fix lint * [HXCS-1166] add documentation * [HXCS-1166] follow PR advices * [HXCS-1166] typos * [HXCS-1166] update testrail id --------- Co-authored-by: Adriano Costa <Adriano.Costa@hyland.comgit>
This commit is contained in:
parent
0c4cc37dd2
commit
cfe158839b
@ -4,10 +4,13 @@
|
||||
<ul>
|
||||
<li>Try setting custom message with unicode characters, for example: <strong>I ♥️ ADF</strong></li>
|
||||
<li>Try setting custom i18n resource key, for example: <strong>APP_LAYOUT.NOTIFICATIONS</strong></li>
|
||||
<li>Try setting a decorative icon, for example <strong>info</strong> or <strong>folder</strong></li>
|
||||
<li>Try toggling the action button. Clicking the action within SnackBar should update the label under the toggle button.</li>
|
||||
<li>All elements support <em>data-automation-id</em> attributes and can be automated.</li>
|
||||
</ul>
|
||||
|
||||
<div>
|
||||
<mat-label class="adf-label">Message:</mat-label>
|
||||
<mat-form-field>
|
||||
<input
|
||||
matInput
|
||||
@ -15,6 +18,18 @@
|
||||
[(ngModel)]="message"
|
||||
data-automation-id="notification-message">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-label class="adf-label">Decorative icon:</mat-label>
|
||||
<mat-form-field>
|
||||
<input
|
||||
matInput
|
||||
placeholder="Decorative Icon"
|
||||
[(ngModel)]="decorativeIcon"
|
||||
data-automation-id="notification-icon">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-slide-toggle
|
||||
|
@ -1,3 +1,7 @@
|
||||
.app-main-content {
|
||||
padding: 10px;
|
||||
|
||||
.adf-label {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import { takeUntil } from 'rxjs/operators';
|
||||
export class NotificationsComponent implements OnInit, OnDestroy {
|
||||
|
||||
message = 'I ♥️ ADF';
|
||||
decorativeIcon = 'folder';
|
||||
withAction = false;
|
||||
actionOutput = '';
|
||||
snackBarConfigObject = '';
|
||||
@ -111,6 +112,9 @@ export class NotificationsComponent implements OnInit, OnDestroy {
|
||||
"duration": "${this.snackBarConfig.duration}",
|
||||
"horizontalPosition": "${ this.snackBarConfig.horizontalPosition}",
|
||||
"verticalPosition": "${ this.snackBarConfig.verticalPosition}"}`;
|
||||
|
||||
this.snackBarConfig.data = { decorativeIcon: this.decorativeIcon };
|
||||
|
||||
if (this.message) {
|
||||
if (this.withAction) {
|
||||
this.notificationService
|
||||
|
@ -120,6 +120,32 @@ export class MyComponent implements OnInit {
|
||||
}
|
||||
```
|
||||
|
||||
By providing a `decorativeIcon` property in the `SnackBarData`, it is possible to render a decorative
|
||||
[`MaterialIcon`](https://material.angular.io/components/icon/overview#interactive-icons) to the left of the message.
|
||||
|
||||
```ts
|
||||
import { NotificationService } from '@alfresco/adf-core';
|
||||
import { MatSnackBarConfig } from '@angular/material/snackbar';
|
||||
|
||||
export class MyComponent implements OnInit {
|
||||
|
||||
snackBarConfig: MatSnackBarConfig = new MatSnackBarConfig();
|
||||
|
||||
constructor(private notificationService: NotificationService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.snackBarConfig.data = { decorativeIcon: 'folder' };
|
||||
this.notificationService
|
||||
.openSnackMessageAction('Do you want to report this issue?', 'send', snackBarConfig)
|
||||
.afterDismissed()
|
||||
.subscribe(() => {
|
||||
console.log('The snack-bar was dismissed');
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The default message duration is 5000 ms that is used only if you don't pass a custom duration in the parameters of openSnackMessageAction/openSnackMessage methods.
|
||||
You can also change the default 5000 ms adding the following configuration in the app.config.json:
|
||||
|
||||
|
@ -67,6 +67,13 @@ describe('Notifications Component', () => {
|
||||
await expect(await notificationPage.snackbarPage.getSnackBarMessage()).toEqual('test');
|
||||
});
|
||||
|
||||
it('[C694098] Should show a decorative icon when the message and the icon fields are not empty and button is clicked', async () => {
|
||||
await notificationPage.enterMessageField('test');
|
||||
await notificationPage.enterDecorativeIconField('folder');
|
||||
await notificationPage.clickNotificationButton();
|
||||
await expect(await notificationPage.snackbarPage.getSnackBarDecorativeIcon()).toEqual('folder');
|
||||
});
|
||||
|
||||
it('[C279978] Should show notification with action when the message is not empty and button is clicked', async () => {
|
||||
await notificationPage.enterMessageField('test');
|
||||
await notificationPage.clickActionToggle();
|
||||
|
@ -23,6 +23,7 @@ export class NotificationDemoPage {
|
||||
snackbarPage = new SnackbarPage();
|
||||
|
||||
messageField = $('input[data-automation-id="notification-message"]');
|
||||
decorativeIconField = $('input[data-automation-id="notification-icon"]');
|
||||
durationField = $('input[data-automation-id="notification-duration"]');
|
||||
actionToggle = $('mat-slide-toggle[data-automation-id="notification-action-toggle"]');
|
||||
notificationSnackBar = $$('simple-snack-bar').first();
|
||||
@ -50,6 +51,10 @@ export class NotificationDemoPage {
|
||||
await BrowserActions.clearSendKeys(this.messageField, text);
|
||||
}
|
||||
|
||||
async enterDecorativeIconField(icon: string): Promise<void> {
|
||||
await BrowserActions.clearSendKeys(this.decorativeIconField, icon);
|
||||
}
|
||||
|
||||
async enterDurationField(time: number): Promise<void> {
|
||||
await BrowserActions.clearSendKeys(this.durationField, time.toString());
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
providers: [NotificationService]
|
||||
})
|
||||
class ProvidesNotificationServiceComponent {
|
||||
|
||||
constructor(public notificationService: NotificationService) {
|
||||
|
||||
}
|
||||
@ -70,6 +71,22 @@ class ProvidesNotificationServiceComponent {
|
||||
return this.notificationService.openSnackMessageAction('Test notification', 'TestWarn', matSnackBarConfig);
|
||||
}
|
||||
|
||||
sendMessageWithDecorativeIcon() {
|
||||
const notificationConfig = new MatSnackBarConfig();
|
||||
notificationConfig.duration = 1000;
|
||||
notificationConfig.data = {decorativeIcon: 'info'};
|
||||
|
||||
return this.notificationService.openSnackMessage('with decorative icon', notificationConfig);
|
||||
}
|
||||
|
||||
sendMessageWithDecorativeIconAndAction() {
|
||||
const notificationConfig = new MatSnackBarConfig();
|
||||
notificationConfig.duration = 1000;
|
||||
notificationConfig.data = { decorativeIcon: 'folder' };
|
||||
|
||||
return this.notificationService.openSnackMessageAction('with decorative icon', 'TestWarn', notificationConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
describe('NotificationService', () => {
|
||||
@ -197,4 +214,27 @@ describe('NotificationService', () => {
|
||||
|
||||
expect(document.querySelector('snack-bar-container')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should open a message notification bar with a decorative icon', (done) => {
|
||||
const promise = fixture.componentInstance.sendMessageWithDecorativeIcon();
|
||||
promise.afterDismissed().subscribe(() => {
|
||||
done();
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(document.querySelector('[data-automation-id="adf-snackbar-message-content"] mat-icon')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should open a message notification bar with action and a decorative icon', (done) => {
|
||||
const promise = fixture.componentInstance.sendMessageWithDecorativeIconAndAction();
|
||||
promise.afterDismissed().subscribe(() => {
|
||||
done();
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(document.querySelector('[data-automation-id="adf-snackbar-message-content"] mat-icon')).not.toBeNull();
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -22,4 +22,5 @@ export interface SnackBarData {
|
||||
message: string;
|
||||
showAction?: boolean;
|
||||
callActionOnIconClick?: boolean;
|
||||
decorativeIcon?: string;
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
<p class="adf-snackbar-message-content" data-automation-id="adf-snackbar-message-content" aria-hidden="true">{{ data.message }}</p>
|
||||
<p class="adf-snackbar-message-content" data-automation-id="adf-snackbar-message-content" aria-hidden="true">
|
||||
<mat-icon *ngIf="data.decorativeIcon" data-automation-id="adf-snackbar-decorative-icon">{{ data.decorativeIcon }}</mat-icon>{{ data.message }}
|
||||
</p>
|
||||
<div *ngIf="data.showAction" class="adf-snackbar-message-content-action" aria-hidden="true">
|
||||
<button mat-button (click)="snackBarRef.dismissWithAction()" *ngIf="data.actionLabel" class="adf-snackbar-message-content-action-button"
|
||||
data-automation-id="adf-snackbar-message-content-action-button">
|
||||
|
@ -4,7 +4,13 @@
|
||||
justify-content: space-between;
|
||||
|
||||
.adf-snackbar-message-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
|
||||
mat-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.adf-snackbar-message-content-action {
|
||||
|
@ -24,6 +24,7 @@ export class SnackbarPage {
|
||||
notificationSnackBar = $$(`[data-automation-id='adf-snackbar-message-content']`).first();
|
||||
snackBarAction = $(`[data-automation-id='adf-snackbar-message-content-action-button']`);
|
||||
snackBarContainerCss = $$('adf-snackbar-content');
|
||||
decorativeIconSnackBar = $(`[data-automation-id='adf-snackbar-decorative-icon']`).first();
|
||||
|
||||
async waitForSnackBarToAppear(timeout = 5000) {
|
||||
return BrowserVisibility.waitUntilElementIsVisible(this.snackBarContainerCss.first(), timeout,
|
||||
@ -45,6 +46,11 @@ export class SnackbarPage {
|
||||
return this.snackBarAction.getText();
|
||||
}
|
||||
|
||||
async getSnackBarDecorativeIcon(): Promise<string> {
|
||||
await this.waitForSnackBarToAppear();
|
||||
return this.decorativeIconSnackBar.getText();
|
||||
}
|
||||
|
||||
async clickSnackBarAction(): Promise<void> {
|
||||
await this.waitForSnackBarToAppear();
|
||||
await BrowserActions.click(this.snackBarAction);
|
||||
|
Loading…
x
Reference in New Issue
Block a user