Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(alert): update alert queue when an alert is removed from the DOM #7189

Merged
merged 7 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions packages/calcite-components/src/components/alert/alert.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,77 @@ describe("calcite-alert", () => {
expect(await container.isVisible()).toBe(false);
});

it("should update number of queued alerts with a calcite-chip when removing an alert", async () => {
const page = await newE2EPage();
await page.setContent(html`
<calcite-button id="buttonOne" onclick="document.querySelector('#first-open').setAttribute('open', '')"
>open alert</calcite-button
>
<calcite-button id="buttonTwo" onclick="document.querySelector('#second-open').setAttribute('open', '')"
>open alert</calcite-button
>
<calcite-button id="buttonThree" onclick="document.querySelector('#third-open').setAttribute('open', '')"
>open alert</calcite-button
>
<calcite-alert open id="first-open" icon="3d-glasses" scale="l">
<div slot="title">Title of alert Uno</div>
<div slot="message">Message text of the alert Uno</div>
<a slot="link" href="#">Retry</a>
</calcite-alert>
<calcite-alert id="second-open" icon scale="l">
<div slot="title">Title of alert Dos</div>
<div slot="message">Message text of the alert Dos</div>
<a slot="link" href="#">Retry</a>
</calcite-alert>
<calcite-alert id="third-open" icon scale="l">
<div slot="title">Title of alert Dos</div>
<div slot="message">Message text of the alert Dos</div>
<a slot="link" href="#">Retry</a>
</calcite-alert>
`);
const buttonOne = await page.find("#buttonOne");
const buttonTwo = await page.find("#buttonTwo");
const buttonThree = await page.find("#buttonThree");
const alertOne = await page.find("#first-open");
const alertTwo = await page.find("#second-open");
const alertThree = await page.find("#third-open");

await buttonOne.click();
await page.waitForTimeout(animationDurationInMs);
expect(await alertOne.isVisible()).toBe(true);

await buttonTwo.click();
expect(await alertTwo.isVisible()).toBe(true);

await buttonThree.click();
expect(await alertThree.isVisible()).toBe(true);

const chip = await page.find("calcite-alert[id='first-open'] >>> calcite-chip");
const chipQueueCount2 = "+2";
expect(await chip.getProperty("value")).toEqual(chipQueueCount2);
expect(chip.textContent).toEqual(chipQueueCount2);

await page.$eval("#third-open", (alert: HTMLCalciteAlertElement) => {
alert.remove();
});
await page.waitForChanges();

const chipQueueCount1 = "+1";
expect(await chip.getProperty("value")).toEqual(chipQueueCount1);
expect(chip.textContent).toEqual(chipQueueCount1);

await page.$eval("#second-open", (alert: HTMLCalciteAlertElement) => {
alert.remove();
});
await page.waitForChanges();

expect(await page.find("calcite-alert[id='first-open'] >>> calcite-chip")).toBeNull();
});

describe("auto-close behavior on queued items", () => {
it("should display number of queued alerts with a calcite-chip", async () => {
const page = await newE2EPage();
Expand Down
20 changes: 19 additions & 1 deletion packages/calcite-components/src/components/alert/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import {
import { Kind, Scale } from "../interfaces";
import { KindIcons } from "../resources";
import { AlertMessages } from "./assets/alert/t9n";
import { AlertDuration, Sync } from "./interfaces";
import { AlertDuration, Sync, Unregister } from "./interfaces";
import { CSS, DURATIONS, SLOTS } from "./resources";

/**
Expand Down Expand Up @@ -203,6 +203,11 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen
}

disconnectedCallback(): void {
window.dispatchEvent(
driskull marked this conversation as resolved.
Show resolved Hide resolved
new CustomEvent<Unregister>("calciteInternalAlertUnregister", {
detail: { alert: this.el }
})
);
window.clearTimeout(this.autoCloseTimeoutId);
window.clearTimeout(this.queueTimeout);
disconnectOpenCloseComponent(this);
Expand Down Expand Up @@ -353,6 +358,19 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen
this.determineActiveAlert();
}

// Event is dispatched on the window because the element is not in the DOM so bubbling won't occur.
@Listen("calciteInternalAlertUnregister", { target: "window" })
alertUnregister(event: CustomEvent<Unregister>): void {
const queue = this.queue.filter((el) => el !== event.detail.alert);
this.queue = queue;

window.dispatchEvent(
new CustomEvent<Sync>("calciteInternalAlertSync", {
detail: { queue }
})
);
}

//--------------------------------------------------------------------------
//
// Public Methods
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export type AlertDuration = "fast" | "medium" | "slow";

export interface Sync {
queue: HTMLCalciteAlertElement[];
}

export interface Unregister {
alert: HTMLCalciteAlertElement;
}