Skip to content

Commit

Permalink
feat(toastr): add toasts limit (#1637)
Browse files Browse the repository at this point in the history
  • Loading branch information
elupanov authored and nnixaa committed Jun 26, 2019
1 parent 838d974 commit 56cac51
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 4 deletions.
6 changes: 6 additions & 0 deletions src/app/playground-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,12 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [
component: 'ToastrStatusesComponent',
name: 'Toastr Statuses',
},
{
path: 'toastr-limit.component',
link: '/toastr/toastr-limit.component',
component: 'ToastrLimitComponent',
name: 'Toastr Limit',
},
],
},
{
Expand Down
4 changes: 4 additions & 0 deletions src/framework/theme/components/toastr/toastr-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ export class NbToastrConfig {
* Determines the how to threat duplicates.
* */
duplicatesBehaviour: NbDuplicateToastBehaviour = 'previous';
/*
* The number of visible toasts. If the limit exceeded the oldest toast will be removed.
* */
limit?: number = null;
/**
* Determines render icon or not.
* */
Expand Down
46 changes: 44 additions & 2 deletions src/framework/theme/components/toastr/toastr.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ describe('toastr-container', () => {
config: { status: 'dander', preventDuplicates: true, duplicatesBehaviour: 'previous' },
};

const toast2 = Object.assign({title: 'toast2'}, toast1);
const toast2 = Object.assign({}, toast1, {title: 'toast2'});

toastrContainer.attach(<NbToast> toast1);
toastrContainer.attach(<NbToast> toast2);
Expand All @@ -272,12 +272,54 @@ describe('toastr-container', () => {
config: { status: 'dander', preventDuplicates: true, duplicatesBehaviour: 'all' },
};

const toast2 = Object.assign({title: 'toast2'}, toast1);
const toast2 = Object.assign({}, toast1, {title: 'toast2'});

toastrContainer.attach(<NbToast> toast1);
toastrContainer.attach(<NbToast> toast2);
const duplicateToast = toastrContainer.attach(<NbToast> toast1);

expect(duplicateToast).toBeUndefined();
});

describe('if limit set', () => {

const toast1 = {
title: 'toast1',
config: { limit: 3 },
};

const toast2 = Object.assign({}, toast1, {title: 'toast2'});
const toast3 = Object.assign({}, toast1, {title: 'toast3'});
const toast4 = Object.assign({}, toast1, {title: 'toast4'});

function attachToasts() {
toastrContainer.attach(<NbToast> toast1);
toastrContainer.attach(<NbToast> toast2);
toastrContainer.attach(<NbToast> toast3);
toastrContainer.attach(<NbToast> toast4);
}

it('should remove the first toast in container in top position', () => {
attachToasts();
expect(containerRefStub.instance.content.length).toEqual(3);
expect(containerRefStub.instance.content[0]).toEqual(toast4);
expect(containerRefStub.instance.content[1]).toEqual(toast3);
expect(containerRefStub.instance.content[2]).toEqual(toast2);
});
it('should remove the last toast in container in bottom position', () => {
positionHelperStub = {
isTopPosition() {
return false;
},
};

toastrContainer = new NbToastContainer(<any> {}, containerRefStub, positionHelperStub);

attachToasts();
expect(containerRefStub.instance.content.length).toEqual(3);
expect(containerRefStub.instance.content[0]).toEqual(toast2);
expect(containerRefStub.instance.content[1]).toEqual(toast3);
expect(containerRefStub.instance.content[2]).toEqual(toast4);
});
});
});
20 changes: 18 additions & 2 deletions src/framework/theme/components/toastr/toastr.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export class NbToastContainer {
return;
}

this.removeToastIfLimitReached(toast);
const toastComponent: NbToastComponent = this.attachToast(toast);

if (toast.config.destroyByClick) {
Expand Down Expand Up @@ -88,6 +89,17 @@ export class NbToastContainer {
&& t1.config.status === t2.config.status;
};

protected removeToastIfLimitReached(toast: NbToast) {
if (!toast.config.limit || this.toasts.length < toast.config.limit) {
return;
}
if (this.positionHelper.isTopPosition(toast.config.position)) {
this.toasts.pop();
} else {
this.toasts.shift();
}
}

protected attachToast(toast: NbToast): NbToastComponent {
if (this.positionHelper.isTopPosition(toast.config.position)) {
return this.attachToTop(toast);
Expand Down Expand Up @@ -220,11 +232,15 @@ export class NbToastrContainerRegistry {
* @stacked-example(Prevent duplicates, toastr/toastr-prevent-duplicates.component)
*
* `duplicatesBehaviour` - determines how to threat the toasts duplication.
* Compare with the previous message (`NbDuplicateToastBehaviour.PREVIOUS`)
* or with all visible messages (`NbDuplicateToastBehaviour.ALL`).
* Compare with the previous message `previous`
* or with all visible messages `all`.
*
* @stacked-example(Prevent duplicates behaviour , toastr/toastr-prevent-duplicates-behaviour.component)
*
* `limit` - the number of visible toasts in the toast container. The number of toasts is unlimited by default.
*
* @stacked-example(Prevent duplicates behaviour , toastr/toastr-limit.component)
*
* `hasIcon` - if true then render toast icon.
* `icon` - you can pass icon class that will be applied into the toast.
*
Expand Down
31 changes: 31 additions & 0 deletions src/playground/with-layout/toastr/toastr-limit.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { NbGlobalLogicalPosition, NbToastrService } from '@nebular/theme';
import { Component } from '@angular/core';

@Component({
selector: 'nb-toastr-limit',
template: `
<button nbButton (click)="showToast()">Show only 3 toasts</button>
`,
styles: [
`
::ng-deep nb-layout-column {
height: 80vw;
}
`,
],
})
export class ToastrLimitComponent {

constructor(private toastrService: NbToastrService) {
}

i: number = 1;

showToast() {
this.toastrService.show(
`Toast number ${this.i}`,
`Toast with the limit`,
{ limit: 3, position: NbGlobalLogicalPosition.TOP_END });
this.i++;
}
}
5 changes: 5 additions & 0 deletions src/playground/with-layout/toastr/toastr-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ToastrPreventDuplicatesComponent } from './toastr-prevent-duplicates.co
import { ToastrShowcaseComponent } from './toastr-showcase.component';
import { ToastrStatusesComponent } from './toastr-statuses.component';
import { ToastrPreventDuplicatesBehaviourComponent } from './toastr-prevent-duplicates-behaviour.component';
import { ToastrLimitComponent } from './toastr-limit.component';

const routes: Route[] = [
{
Expand Down Expand Up @@ -48,6 +49,10 @@ const routes: Route[] = [
path: 'toastr-statuses.component',
component: ToastrStatusesComponent,
},
{
path: 'toastr-limit.component',
component: ToastrLimitComponent,
},
];

@NgModule({
Expand Down
2 changes: 2 additions & 0 deletions src/playground/with-layout/toastr/toastr.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ToastrPositionsComponent } from './toastr-positions.component';
import { ToastrPreventDuplicatesComponent } from './toastr-prevent-duplicates.component';
import { ToastrShowcaseComponent } from './toastr-showcase.component';
import { ToastrStatusesComponent } from './toastr-statuses.component';
import { ToastrLimitComponent } from './toastr-limit.component';
import { ToastrPreventDuplicatesBehaviourComponent } from './toastr-prevent-duplicates-behaviour.component';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
Expand All @@ -28,6 +29,7 @@ import { FormsModule } from '@angular/forms';
ToastrPreventDuplicatesBehaviourComponent,
ToastrShowcaseComponent,
ToastrStatusesComponent,
ToastrLimitComponent,
],
imports: [
CommonModule,
Expand Down

0 comments on commit 56cac51

Please sign in to comment.