Skip to content

fix(webapp): correct button disabling state broken by Remix v2 useNav…#4235

Closed
Naresh-official wants to merge 1 commit into
triggerdotdev:mainfrom
Naresh-official:fix/prevent-duplicate-alert-creation
Closed

fix(webapp): correct button disabling state broken by Remix v2 useNav…#4235
Naresh-official wants to merge 1 commit into
triggerdotdev:mainfrom
Naresh-official:fix/prevent-duplicate-alert-creation

Conversation

@Naresh-official

Copy link
Copy Markdown

Summary

This PR fixes an issue where loading states were no longer activated for several form submissions after the Remix v2 upgrade.

navigation.formMethod now returns uppercase HTTP methods (e.g. "POST"), while the existing code was still comparing against lowercase ("post"). As a result, the loading state was never triggered, leaving action buttons enabled during submissions.

On the Alerts page, this allowed users to click Save multiple times before the first request completed, resulting in duplicate alert channels being created.

Fixes #3455


Problem

Several routes determine whether a form is submitting using logic similar to:

const isLoading =
  navigation.state !== "idle" &&
  navigation.formMethod === "post" &&
  navigation.formData?.get("action") === "create";

With Remix v2, navigation.formMethod is now uppercase ("POST"). Since the comparison never matched, isLoading always remained false.

This caused:

  • Submit buttons to remain enabled during requests.
  • Loading indicators to never appear.
  • Multiple rapid submissions to be possible on slower networks or high-latency connections.

Solution

Updated the affected routes to compare against the correct uppercase HTTP method:

navigation.formMethod === "POST"

This restores the expected loading state behavior across the affected forms, ensuring that action buttons are disabled while a submission is in progress.

The change applies to:

  • Creating alert channels
  • Deleting alert channels
  • Enabling/disabling alert channels
  • Creating environment variables
  • Deleting environment variables
  • Renaming dashboards
  • Deleting dashboards

Testing

  • Verified that the loading state is correctly activated during form submission.
  • Verified that action buttons are disabled while the request is in progress.
  • Reproduced the original issue by rapidly clicking Save on the Alerts page.
  • Confirmed that only a single alert channel is created after this change.

@changeset-bot

changeset-bot Bot commented Jul 11, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 8805d13

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ba66b7f7-2f89-4741-9d62-359656124bc5

📥 Commits

Reviewing files that changed from the base of the PR and between 2cac63f and 8805d13.

📒 Files selected for processing (5)
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.alerts.new/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.alerts/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboards.custom.$dashboardId/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables.new/route.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.environment-variables/route.tsx

Walkthrough

Updated loading-state conditions across alert, dashboard, and environment-variable routes to compare navigation.formMethod with uppercase "POST" instead of lowercase "post". These conditions control disabled states, loading labels, and dialog behavior during create, rename, delete, enable, and disable submissions.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Hi @Naresh-official, thanks for your interest in contributing!

This project requires that pull request authors are vouched, and you are not in the list of vouched users.

This PR will be closed automatically. See https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md for more details.

@github-actions github-actions Bot closed this Jul 11, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

Open in Devin Review

Comment on lines +425 to 426
navigation.formMethod === "POST" &&
navigation.formData?.get("action") === "delete";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Disable-alert button never shows its loading indicator

The loading-state check looks for the action value "delete" (navigation.formData?.get("action") === "delete" at apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.alerts/route.tsx:426) but the button actually submits "disable" (line 444), so the condition is never true and the button text stays as "Disable" instead of changing to "Disabling" during submission.

Impact: Users get no visual feedback that the disable action is in progress.

Action value mismatch inherited from copy-paste of DeleteAlertChannelButton

The DisableAlertChannelButton component's isLoading expression was copy-pasted from DeleteAlertChannelButton at apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.alerts/route.tsx:384-387, which correctly checks for "delete". The value was never updated to "disable" to match the button at line 444:

<Button name="action" value="disable" ...>
  {isLoading ? "Disabling" : "Disable"}
</Button>

Before this PR, the bug was masked because formMethod === "post" (lowercase) never matched Remix v2's uppercase "POST", making isLoading always false for a different reason. Now that the PR correctly uses "POST", this action-value mismatch becomes the sole reason isLoading is broken.

Suggested change
navigation.formMethod === "POST" &&
navigation.formData?.get("action") === "delete";
navigation.formMethod === "POST" &&
navigation.formData?.get("action") === "disable";
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +465 to 466
navigation.formMethod === "POST" &&
navigation.formData?.get("action") === "delete";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Enable-alert button never shows its loading indicator

The loading-state check looks for the action value "delete" (navigation.formData?.get("action") === "delete" at apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.alerts/route.tsx:466) but the button actually submits "enable" (line 484), so the condition is never true and the button text stays as "Enable" instead of changing to "Enabling" during submission.

Impact: Users get no visual feedback that the enable action is in progress.

Action value mismatch inherited from copy-paste of DeleteAlertChannelButton

The EnableAlertChannelButton component's isLoading expression was copy-pasted from DeleteAlertChannelButton at apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.alerts/route.tsx:384-387, which correctly checks for "delete". The value was never updated to "enable" to match the button at line 484:

<Button name="action" value="enable" ...>
  {isLoading ? "Enabling" : "Enable"}
</Button>

Before this PR, the bug was masked because formMethod === "post" (lowercase) never matched Remix v2's uppercase "POST", making isLoading always false for a different reason. Now that the PR correctly uses "POST", this action-value mismatch becomes the sole reason isLoading is broken.

Suggested change
navigation.formMethod === "POST" &&
navigation.formData?.get("action") === "delete";
navigation.formMethod === "POST" &&
navigation.formData?.get("action") === "enable";
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@Naresh-official Naresh-official deleted the fix/prevent-duplicate-alert-creation branch July 11, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Alerts page creates duplicate alerts when Save is clicked multiple times

1 participant