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: resolve swal promise when its dismissed by another swal #2689

Merged

Conversation

limonte
Copy link
Member

@limonte limonte commented Nov 19, 2023

closes #2681

Summary by CodeRabbit

  • New Features

    • Enhanced modal interaction by allowing a SweetAlert modal to be dismissed by another modal, improving user experience with chained modals.
  • Bug Fixes

    • Ensured that promises are correctly resolved when a modal is dismissed by another modal, maintaining the reliability of modal behavior.
  • Tests

    • Added new end-to-end tests to verify the correct dismissal and promise resolution of SweetAlert modals.
  • Chores

    • Updated .gitignore to exclude the cypress/downloads directory, keeping the repository clean from test artifacts.

Copy link
Contributor

coderabbitai bot commented Nov 19, 2023

Walkthrough

The recent updates to the codebase focus on ensuring that promises from SweetAlert2 dialogs are properly resolved or rejected when a dialog is interrupted by another, such as a toast notification. This change addresses a specific issue where promises were left hanging in such scenarios, leading to potential bugs in applications using SweetAlert2.

Changes

File Path Change Summary
.gitignore Added cypress/downloads to the list of ignored directories.
cypress/e2e/.../tests.cy.js Added test cases for the 'swal dismissed by another swal' functionality.
src/SweetAlert.js Updated the SweetAlert class to handle promise resolution when a Swal dialog is interrupted by another.

Assessment against linked issues

Objective Addressed Explanation
#2681: Ensure Swal dialog's promise resolves or rejects when interrupted by a toast The changes in src/SweetAlert.js address this by resolving the promise with { isDismissed: true } when a Swal dialog is interrupted.
#2681: Verify behavior with a live demo The assessment is limited to code changes, and manual testing instructions are not within the scope of this review.

As autumn leaves do gently fall, 🍂
We code away, through bugs and all.
SweetAlert's promise, now steadfast,
Ensures no dialog's fate is miscast. 🐇✨


Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • If you reply to a review comment from CodeRabbit, the bot will automatically respond.
  • To engage with CodeRabbit bot directly around the specific lines of code in the PR, mention @coderabbitai in your review comment
  • Note: Review comments are made on code diffs or files, not on the PR overview.
  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Note: For conversation with the bot, please use the review comments on code diffs or files.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 238c7e2 and 5dac0d9.
Files selected for processing (3)
  • .gitignore (1 hunks)
  • cypress/e2e/tests.cy.js (1 hunks)
  • src/SweetAlert.js (1 hunks)
Files skipped from review due to trivial changes (1)
  • .gitignore
Additional comments: 2
cypress/e2e/tests.cy.js (2)
  • 489-497: This test case checks if a SweetAlert modal is dismissed by another SweetAlert modal, the promise should resolve with { isDismissed: true }. The test case is correctly structured to simulate the scenario and validate the expected outcome. However, it's important to ensure that the dismissal of the first modal by the second modal is intentional and not due to a race condition or a bug in the implementation.

  • 499-511: This test case is designed to ensure that if a SweetAlert modal is dismissed by another modal after clickConfirm() is called, the promise resolves with the expected values indicating that the modal was confirmed. It's crucial to verify that the behavior of clickConfirm() followed by another modal invocation is consistent with the intended logic and that there are no side effects or race conditions.

Comment on lines 54 to 65
showWarningsForParams(Object.assign({}, mixinParams, userParams))

if (globalState.currentInstance) {
const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance)
const { isAwaitingPromise } = globalState.currentInstance
globalState.currentInstance._destroy()
if (!isAwaitingPromise) {
swalPromiseResolve({ isDismissed: true })
}
if (dom.isModal()) {
unsetAriaHidden()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes here address the issue described in the pull request summary. The logic checks if there is an existing currentInstance and if it is not awaiting a promise, it resolves the promise with { isDismissed: true }. This ensures that the promise is resolved when a modal is dismissed by another modal. Additionally, the check for dom.isModal() and the call to unsetAriaHidden() are important for accessibility reasons, ensuring that screen readers can correctly interpret the state of the application when modals are dismissed.

However, there is a potential issue with the current implementation. The unsetAriaHidden() function is called without checking if the current modal is the one being dismissed. If there are multiple modals, this could lead to incorrect behavior where aria-hidden attributes are removed from elements that are not currently visible. This should be verified and tested to ensure that it behaves as expected in scenarios with multiple modals.

-      if (dom.isModal()) {
+      if (dom.isModal() && !isAwaitingPromise) {
        unsetAriaHidden()
      }

By adding the !isAwaitingPromise condition, we ensure that unsetAriaHidden() is only called when the current modal is actually being dismissed and not awaiting another promise.


Commitable suggestion

[!IMPORTANT]
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
showWarningsForParams(Object.assign({}, mixinParams, userParams))
if (globalState.currentInstance) {
const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance)
const { isAwaitingPromise } = globalState.currentInstance
globalState.currentInstance._destroy()
if (!isAwaitingPromise) {
swalPromiseResolve({ isDismissed: true })
}
if (dom.isModal()) {
unsetAriaHidden()
}
showWarningsForParams(Object.assign({}, mixinParams, userParams))
if (globalState.currentInstance) {
const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance)
const { isAwaitingPromise } = globalState.currentInstance
globalState.currentInstance._destroy()
if (!isAwaitingPromise) {
swalPromiseResolve({ isDismissed: true })
}
if (dom.isModal() && !isAwaitingPromise) {
unsetAriaHidden()
}

@limonte limonte merged commit 0b4329b into main Nov 19, 2023
2 checks passed
@limonte limonte deleted the fix/resolve-swal-promise-when-its-dismissed-by-other-swal branch November 19, 2023 15:07
github-actions bot pushed a commit that referenced this pull request Nov 19, 2023
## [11.10.1](v11.10.0...v11.10.1) (2023-11-19)

### Bug Fixes

* resolve swal promise when its dismissed by another swal ([#2689](#2689)) ([0b4329b](0b4329b))
@limonte
Copy link
Member Author

limonte commented Nov 19, 2023

🎉 This PR is included in version 11.10.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@Tofnet
Copy link

Tofnet commented Jan 4, 2024

For those looking to detect the dismissal of a Swal modal by another modal within the promise, I've found a solution that works well. I use the following check:
if (result.isDismissed && result.dismiss === undefined) return;
This effectively prevents the execution of subsequent code when the Swal is dismissed automatically by another Swal, maintaining the intended behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

If a Swal dialog is interrupted by a toast, promise never resolves or rejects
2 participants