[HXCS-1166] follow PR advices

This commit is contained in:
Adriano Costa
2023-03-20 16:52:05 +01:00
parent 06790b9092
commit 9eb3d98bfc
11 changed files with 73 additions and 49 deletions

View File

@@ -4,17 +4,32 @@
<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>
<mat-form-field>
<input
matInput
placeholder="Message"
[(ngModel)]="message"
data-automation-id="notification-message">
</mat-form-field>
<div>
<mat-label class="adf-label">Message:</mat-label>
<mat-form-field>
<input
matInput
placeholder="Message"
[(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

View File

@@ -1,3 +1,7 @@
.app-main-content {
padding: 10px;
.adf-label {
margin-right: 12px;
}
}

View File

@@ -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

View File

@@ -120,30 +120,22 @@ export class MyComponent implements OnInit {
}
```
By providing a `templateRef` property in the `SnackBarData`, it is possible to render a custom [`TemplateRef`]( https://angular.io/api/core/TemplateRef) in place of the text message.
The message is made available within the template through a context property (eg: `let-message`).
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';
@Component({
template: `<ng-template #customTemplate let-message >
<span><i>Custom content:</i> {{ message }}</span>
</ng-template>`,
providers: [NotificationService]
})
export class MyComponent implements OnInit {
snackBarConfig: MatSnackBarConfig = new MatSnackBarConfig();
@ViewChild('customTemplate', { read: TemplateRef }) customTemplate: TemplateRef<any>;
constructor(private notificationService: NotificationService) {
}
ngOnInit() {
this.snackBarConfig.data = { templateRef: this.customTemplate };
this.snackBarConfig.data = { decorativeIcon: 'folder' };
this.notificationService
.openSnackMessageAction('Do you want to report this issue?', 'send', snackBarConfig)
.afterDismissed()

View File

@@ -67,6 +67,13 @@ describe('Notifications Component', () => {
await expect(await notificationPage.snackbarPage.getSnackBarMessage()).toEqual('test');
});
it('[???????] 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();

View File

@@ -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());
}

View File

@@ -17,7 +17,7 @@
import { LiveAnnouncer } from '@angular/cdk/a11y';
import { OverlayModule } from '@angular/cdk/overlay';
import { Component, TemplateRef, ViewChild } from '@angular/core';
import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatSnackBar, MatSnackBarConfig, MatSnackBarModule } from '@angular/material/snack-bar';
@@ -28,15 +28,10 @@ import { CoreTestingModule } from '../../testing/core.testing.module';
import { TranslateModule } from '@ngx-translate/core';
@Component({
template: `<ng-template #customTemplate let-message>
<p class="custom-template-class">Custom content {{message}}</p>
</ng-template>`,
providers: [NotificationService]
})
class ProvidesNotificationServiceComponent {
@ViewChild('customTemplate', { read: TemplateRef }) customTemplate: TemplateRef<any>;
constructor(public notificationService: NotificationService) {
}
@@ -75,20 +70,20 @@ class ProvidesNotificationServiceComponent {
return this.notificationService.openSnackMessageAction('Test notification', 'TestWarn', matSnackBarConfig);
}
sendMessageWithTemplateRef() {
sendMessageWithDecorativeIcon() {
const notificationConfig = new MatSnackBarConfig();
notificationConfig.duration = 1000;
notificationConfig.data = {templateRef: this.customTemplate};
notificationConfig.data = {decorativeIcon: 'info'};
return this.notificationService.openSnackMessage('with templateRef', notificationConfig);
return this.notificationService.openSnackMessage('with decorative icon', notificationConfig);
}
sendMessageWithTemplateRefWithAction() {
sendMessageWithDecorativeIconWithIcon() {
const notificationConfig = new MatSnackBarConfig();
notificationConfig.duration = 1000;
notificationConfig.data = { templateRef: this.customTemplate };
notificationConfig.data = { decorativeIcon: 'folder' };
return this.notificationService.openSnackMessageAction('with templateRef', 'TestWarn', notificationConfig);
return this.notificationService.openSnackMessageAction('with decorative icon', 'TestWarn', notificationConfig);
}
}
@@ -219,28 +214,26 @@ describe('NotificationService', () => {
expect(document.querySelector('snack-bar-container')).not.toBeNull();
});
it('should open a message notification bar with a custom templateRef configuration', (done) => {
const promise = fixture.componentInstance.sendMessageWithTemplateRef();
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('.custom-template-class')).not.toBeNull();
expect(document.querySelector('.custom-template-class')?.innerHTML).toEqual('Custom content with templateRef');
expect(document.querySelector('[data-automation-id="adf-snackbar-message-content"] mat-icon')).not.toBeNull();
});
it('should open a message notification bar with action and custom templateRef configuration', (done) => {
const promise = fixture.componentInstance.sendMessageWithTemplateRefWithAction();
it('should open a message notification bar with action and decorative icon', (done) => {
const promise = fixture.componentInstance.sendMessageWithDecorativeIconWithIcon();
promise.afterDismissed().subscribe(() => {
done();
});
fixture.detectChanges();
expect(document.querySelector('.custom-template-class')).not.toBeNull();
expect(document.querySelector('.custom-template-class')?.innerHTML).toEqual('Custom content with templateRef');
});
expect(document.querySelector('[data-automation-id="adf-snackbar-message-content"] mat-icon')).not.toBeNull();
});
});

View File

@@ -15,8 +15,6 @@
* limitations under the License.
*/
import { TemplateRef } from '@angular/core';
export interface SnackBarData {
actionLabel?: string;
actionIcon?: string;
@@ -24,5 +22,5 @@ export interface SnackBarData {
message: string;
showAction?: boolean;
callActionOnIconClick?: boolean;
templateRef?: TemplateRef<any>;
decorativeIcon?: string;
}

View File

@@ -1,11 +1,5 @@
<p class="adf-snackbar-message-content" data-automation-id="adf-snackbar-message-content" aria-hidden="true">
<ng-container *ngIf="!data.templateRef else customTemplate">{{ data.message }}</ng-container>
<ng-template #customTemplate>
<ng-container
[ngTemplateOutlet]="data.templateRef"
[ngTemplateOutletContext]="{ $implicit: data.message}">
</ng-container>
</ng-template>
<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"

View File

@@ -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 {

View File

@@ -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);