Skip to content

Commit

Permalink
Merge pull request #28 from ngxpert/fix/issue-9
Browse files Browse the repository at this point in the history
Fix/issue 9
  • Loading branch information
shhdharmen authored Dec 7, 2024
2 parents 39347a7 + 7adb2d1 commit 8ffc08e
Show file tree
Hide file tree
Showing 12 changed files with 305 additions and 30 deletions.
114 changes: 114 additions & 0 deletions cypress/e2e/toast_grouping.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/// <reference types="cypress" />

describe('Toast Grouping', () => {
beforeEach(() => {
cy.visit('/');
cy.get('#grouping').scrollIntoView();
});

it('should show pre-grouped notifications', () => {
// Click the pre-grouping example button
cy.get('#grouping-pre').click();

// Check parent toast appears with retry and longer timeout
cy.get('.hot-toast-bar-base', { timeout: 10000 }).should('be.visible');
cy.get('.hot-toast-bar-base').within(() => {
cy.contains('New Activities', { timeout: 5000 }).should('be.visible');
cy.contains('5 New Activities', { timeout: 5000 }).should('be.visible');
cy.contains("What's happening around you!", { timeout: 5000 }).should('be.visible');
});

// Check expand/collapse functionality with wait
cy.get('.hot-toast-group-btn').should('be.visible').click();
cy.wait(500); // Wait for expansion animation

// Verify all child notifications are visible
cy.get('.hot-toast-bar-base-group').within(() => {
cy.contains('New Message!', { timeout: 5000 }).should('be.visible');
cy.contains('Level Up!', { timeout: 5000 }).should('be.visible');
cy.contains('Reminder: Meeting Today', { timeout: 5000 }).should('be.visible');
cy.contains('Special Offer!', { timeout: 5000 }).should('be.visible');
cy.contains('Task Assigned', { timeout: 5000 }).should('be.visible');
cy.contains('Sarah sent you a message.', { timeout: 5000 }).should('be.visible');
cy.contains('Just Now', { timeout: 5000 }).should('be.visible');
});

// Test collapse with wait
cy.get('.hot-toast-group-btn').should('be.visible').click();
cy.wait(500); // Wait for collapse animation

// Verify collapsed state
cy.get('.hot-toast-bar-base-group').within(() => {
cy.contains('New Message!', { timeout: 5000 }).should('not.be.visible');
});
});

it('should handle dynamic notifications', () => {
const titles = ['New Message!', 'Level Up!', 'Reminder: Meeting Today'];

cy.get('#grouping-post').click();
cy.get('.hot-toast-bar-base', { timeout: 10000 }).should('be.visible');

titles.forEach(() => {
cy.contains('Add notification').click();
cy.wait(200);
});

cy.get('.hot-toast-group-btn').should('be.visible').click();
cy.wait(500);

cy.get('.hot-toast-bar-base-group')
.find('.hot-toast-bar-base')
.should('have.length', titles.length)
.each((el, index) => {
expect(el).to.contain(titles[index]);
});
});

it('should handle dismissible notifications', () => {
// Force click the hidden test button
cy.get('#test-dismissible-toasts').click({ force: true });

// Check parent toast appears with retry and longer timeout
cy.get('.hot-toast-bar-base', { timeout: 10000 }).should('be.visible');
cy.get('.hot-toast-bar-base').within(() => {
// Wait for all notifications to be added and visible
cy.contains(/[0-5] New Activities/, { timeout: 10000 }).should('be.visible');
cy.contains("What's happening around you!", { timeout: 5000 }).should('be.visible');
cy.get('.hot-toast-close-btn').should('be.visible');
});

// Check expand/collapse functionality with wait
cy.get('.hot-toast-group-btn').should('be.visible').click();
cy.wait(500); // Wait for expansion animation

// Verify all child notifications are visible and have close buttons
cy.get('.hot-toast-bar-base-group').within(() => {
cy.contains('New Message!', { timeout: 5000 }).should('be.visible');
cy.contains('Level Up!', { timeout: 5000 }).should('be.visible');
cy.contains('Reminder: Meeting Today', { timeout: 5000 }).should('be.visible');
cy.contains('Special Offer!', { timeout: 5000 }).should('be.visible');
cy.contains('Task Assigned', { timeout: 5000 }).should('be.visible');
cy.contains('Sarah sent you a message.', { timeout: 5000 }).should('be.visible');
cy.contains('Just Now', { timeout: 5000 }).should('be.visible');

// Check close buttons in child notifications
cy.get('.hot-toast-close-btn').should('have.length.at.least', 1);
});

// Test close functionality
cy.get('.hot-toast-bar-base-group').within(() => {
cy.get('.hot-toast-close-btn').first().click();
cy.contains('New Message!', { timeout: 5000 }).should('not.exist');
});

// Test collapse with wait
cy.get('.hot-toast-group-btn').should('be.visible').click();
cy.wait(500); // Wait for collapse animation

// Verify collapsed state
cy.get('.hot-toast-bar-base-group').within(() => {
cy.contains('Level Up!', { timeout: 5000 }).should('not.be.visible');
});
});
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"start:lib": "ng build @ngxpert/hot-toast --watch",
"build": "ng build",
"unit": "npm run cy:open",
"test": "npm run ci:cy-run",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class HotToastGroupItemComponent implements OnChanges, OnInit, AfterViewI
}

get groupChildrenToastRefs() {
return this.toastRef.groupRefs;
return this.toastRef.groupRefs.filter((ref) => !!ref);
}
set groupChildrenToastRefs(value: CreateHotToastRef<unknown>[]) {
(this.toastRef as { groupRefs: CreateHotToastRef<unknown>[] }).groupRefs = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
}
</div>

@if (toast.visible) {
<div
role="list"
class="hot-toast-bar-base-group"
Expand All @@ -78,5 +79,6 @@
></hot-toast-group-item>
}
</div>
}
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export class HotToastComponent implements OnInit, AfterViewInit, OnDestroy, OnCh
}

get groupChildrenToastRefs() {
return this.groupRefs;
return this.groupRefs.filter((ref) => !!ref);
}
set groupChildrenToastRefs(value: CreateHotToastRef<unknown>[]) {
this.groupRefs = value;
Expand Down
86 changes: 86 additions & 0 deletions projects/ngxpert/hot-toast/src/lib/hot-toast-builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Content } from '@ngneat/overview';
import { CreateHotToastRef, ToastOptions } from './hot-toast.model';
import { HotToastService } from './hot-toast.service';
import { Observable } from 'rxjs';

type ToastMethod = 'show' | 'success' | 'error' | 'warning' | 'info' | 'loading';

export class HotToastBuilder<DataType = unknown> {
private options: ToastOptions<DataType>;
private groupChildren: HotToastBuilder<unknown>[] = [];
private toastRef: CreateHotToastRef<DataType>;

constructor(private message: Content, private service: HotToastService) {
this.options = {};
}

setOptions(options: ToastOptions<DataType>): this {
this.options = { ...this.options, ...options };
return this;
}

addChild(child: HotToastBuilder<unknown>): this {
this.groupChildren.push(child);
return this;
}

get afterGroupRefsAttached(): Observable<CreateHotToastRef<unknown>[]> {
return this.toastRef?.afterGroupRefsAttached;
}

private addChildrenToOptions() {
if (this.groupChildren.length > 0) {
const children = this.groupChildren.map((child) => ({
options: {
message: child.message,
...child.options,
},
}));

this.options.group = {
...this.options.group,
children,
};
}
}

// Create method that creates but doesn't show the toast. Call show() to show the toast.
create(method: ToastMethod = 'show'): CreateHotToastRef<DataType> {
this.addChildrenToOptions();
this.toastRef = this.service[method](this.message, {
...this.options,
...{ visible: false },
}) as CreateHotToastRef<DataType>;
return this.toastRef;
}

private createToast(method: ToastMethod): CreateHotToastRef<DataType> {
this.addChildrenToOptions();
this.toastRef = this.service[method](this.message, this.options) as CreateHotToastRef<DataType>;
return this.toastRef;
}

show(): CreateHotToastRef<DataType> {
return this.createToast('show');
}

success(): CreateHotToastRef<DataType> {
return this.createToast('success');
}

error(): CreateHotToastRef<DataType> {
return this.createToast('error');
}

warning(): CreateHotToastRef<DataType> {
return this.createToast('warning');
}

info(): CreateHotToastRef<DataType> {
return this.createToast('info');
}

loading(): CreateHotToastRef<DataType> {
return this.createToast('loading');
}
}
6 changes: 6 additions & 0 deletions projects/ngxpert/hot-toast/src/lib/hot-toast-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export class HotToastRef<DataType = DefaultDataType> implements HotToastRefProps
/** Subject for notifying the user that the toast has been closed. */
private _onGroupToggle = new Subject<HotToastGroupEvent>();

private _componentRef: { changeDetectorRef: { detectChanges: () => void } };

constructor(private toast: Toast<DataType>) {}

set data(data: DataType) {
Expand Down Expand Up @@ -87,4 +89,8 @@ export class HotToastRef<DataType = DefaultDataType> implements HotToastRefProps
event: this.groupExpanded ? 'expand' : 'collapse',
});
}

show() {
this.toast.visible = true;
}
}
1 change: 1 addition & 0 deletions projects/ngxpert/hot-toast/src/lib/hot-toast.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export interface HotToastRefProps<DataType> {
* @since 1.1.0
*/
toggleGroup: (eventData?: { byAction: boolean }) => void;
show: () => void;
}

/** Event that is emitted when a toast is dismissed. */
Expand Down
1 change: 1 addition & 0 deletions projects/ngxpert/hot-toast/src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './lib/hot-toast.service';
export * from './lib/hot-toast.provide';
export * from './lib/hot-toast.model';
export * from './lib/hot-toast-ref';
export * from './lib/hot-toast-builder';
4 changes: 4 additions & 0 deletions src/app/sections/grouping/grouping.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,7 @@ <h2 class="ml-5 mr-5 mb-4 text-2xl font-bold">
</div>
</div>
</ng-template>
<div style="display: none;">
<!-- Test buttons for toast options -->
<button id="test-dismissible-toasts" (click)="showDismissibleToasts()"></button>
</div>
Loading

0 comments on commit 8ffc08e

Please sign in to comment.