You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The delete organization button runs CheckOrganizationDelete on click, with a spinner on the button. When something blocks the delete, an "Unable to delete" dialog lists the blockers. Otherwise the confirmation opens.
A refused delete (FAILED_PRECONDITION with PreconditionFailure violations) closes the confirmation and opens the same blocked dialog. A FAILED_PRECONDITION with no violations comes from a disabled organization and shows as its own blocker.
FrontierProvider takes a slots prop. Its deleteBlockedDialog slot lets a host app word the blocked dialog in one place. The slot returns DeleteBlockedDialog (title, description, blockers, messages), its own AlertDialog.Content to replace the whole dialog, or undefined for the SDK's own dialog. A bullet is messages[subject], else messages[type], else the SDK line. Identical lines show once, and blockers with no line share one generic line.
A refused delete whose blockers can't be read shows a toast instead of the dialog.
DeleteBlocker (type, subject, count) is the SDK's own shape. A check response and a refused delete both map to it. The server's developer message is left out.
useDeleteCheck runs the check, then opens the confirmation or the blocked dialog. The project flow in the next PR uses it too.
Bumps @raystack/proton to 94668c36, the commit the server builds from.
The delete organization button no longer checks the blockers on page load
and stays disabled with a tooltip. On click it runs checkOrganizationDelete
with a loading state. If the delete is blocked, a dialog lists the
blockers; otherwise the delete dialog opens.
A disabled organization fails the check with FAILED_PRECONDITION, so it
shows as a blocker in the same dialog. Any other check error shows a
toast. The delete button keeps its label while the check runs.
It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.
Added an organization deletion flow that checks eligibility before showing the confirmation dialog and displays a checking state.
Added a blocked-deletion dialog that explains why deletion cannot proceed, with customizable content and messages.
Added SDK options for customizing the blocked-deletion experience.
Bug Fixes
Improved deletion error feedback for blocked deletions, permission issues, and organizations that cannot be found.
The SDK now parses deletion blockers into typed data, formats blocker messages, and supports a customizable blocked-delete dialog. The organization view checks deletion eligibility when deletion starts and routes the result to the confirmation or blocked dialog.
Changes: Organization deletion flow
Layer / File(s)
Summary
Blocker data and messages web/sdk/shared/types.ts, web/sdk/client/utils/delete-blockers.ts, web/sdk/client/utils/delete-blockers.test.ts
The SDK adds a typed blocker shape and maps precondition violations to blockers. Message formatting supports subject-specific and type-specific text, removes duplicate lines, and adds a generic line when needed. The previous tests for blocker wording and error parsing are removed.
Blocked-delete dialog and provider slot web/sdk/shared/types.ts, web/sdk/client/contexts/FrontierContext.tsx, web/sdk/client/components/delete-blocked-dialog/*, web/sdk/client/index.ts
The provider accepts optional slots, including a blocked-delete dialog slot. The dialog host passes blocker context to the slot and renders the default dialog when the slot result is null or boolean. The SDK exports the dialog and related types.
Deletion check and confirmation flow web/sdk/client/hooks/useDeleteFlow.ts, web/sdk/client/views/general/general-view.tsx, web/sdk/client/views/general/components/delete-organization-dialog.tsx, web/sdk/client/views/general/general-view.module.css, web/sdk/package.json
The organization view starts an eligibility check from the Delete button and shows a loading state while checking. The flow opens the confirmation or blocked dialog and routes errors. The confirmation dialog uses an alert-dialog handle and forwards deletion errors. The pinned Proton revision changes.
raystack/frontier#2017: Adds organization resource blockers to the check response and delete precondition path consumed by this SDK flow.
raystack/frontier#2005: Adds the blocker type and count field that the SDK blocker model carries.
raystack/frontier#2011: Passes blocker counts through the check response that the SDK copies into DeleteBlocker.
Merge Risk: Low · previous review 5cacc
The change is mergeable with awareness of remaining dialog issues: blocker explanations can be missing or stale, and switching organizations during a check can open an unchecked confirmation. Server-side deletion safeguards remain intact.
Pre-merge checks: 2
Check name
Status
Explanation
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Tip
🎯 Customize your risk assessments
Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.
✅ Automatic approvals, with your rules
Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.
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.
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.
Close the shared handle before invoking the success callback.
DeleteOrganizationForm invokes onDeleteSuccess without closing the AlertDialog. The demo callback navigates away, but the module-scoped handle retains its open state. Returning to GeneralView can reopen the confirmation dialog.
Close the handle in DeleteOrganizationDialog, where handle is in scope:
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
@rohanchkrabrty CodeRabbit flagged this outside the diff, and it's real. The handles live at module level, and Base UI doesn't reset open when the dialog unmounts. After a delete, onDeleteSuccess navigates away but the handle still says open, so the confirm dialog pops up again the next time the settings page mounts. Can we close the handle before calling onDeleteSuccess? Creating the handles inside GeneralView with useState(() => AlertDialog.createHandle()) would also stop two views from sharing state.
The reason will be displayed to describe this comment to others. Learn more.
Nothing passes enabled to useTokens anymore, but the comment on that option in client/hooks/useTokens.ts still says the delete dialog uses it. Can we drop the option and its comment?
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 6277d9b. Ran prettier on this file, on components/delete-blocked-dialog/delete-blocked-dialog.tsx (the renamed blockers dialog), and on hooks/useDeleteCheck.ts. The extra blank line is gone.
The reason will be displayed to describe this comment to others. Learn more.
These three toasts are copies of the ones in delete-organization-dialog.tsx, and the lines run past 130 characters. Could we move them into one shared handler and run prettier?
The reason will be displayed to describe this comment to others. Learn more.
Nit: AlertDialog.Content has no width prop. tsc flags it, and it ends up as an unused attribute on the div, so it doesn't set the width. The new blockers dialog uses a class for this. Could this one do the same?
FrontierProvider takes a slots prop. Its deleteBlockedDialog slot gets the
blockers of a delete and returns a DeleteBlockedDialog with the host app's
title, description and one line per resource namespace or blocker type.
With no slot, or when the slot returns undefined, the SDK shows its own
dialog.
DeleteBlocker is the SDK's own shape for a blocker. A delete check and a
refused delete both give it, without the server's developer message.
The organization delete uses a shared useDeleteFlow hook: check on click,
then open the confirmation or the blocked dialog. A refused delete now
closes the confirmation and shows the blocked dialog instead of a toast.
A failed_precondition with no violations means a disabled organization.
Bumps @raystack/proton to 94668c36, the commit the server builds from.
rohanchkrabrty
changed the title
feat(sdk): check org delete blockers on click and show a dialog
feat(sdk): check org delete blockers on click and let the host app word the dialog
Nov 3, 2026
rohanchkrabrty
changed the title
feat(sdk): check org delete blockers on click and let the host app word the dialog
feat(sdk): org delete blockers UI
Nov 3, 2026
The reason will be displayed to describe this comment to others. Learn more.
Follow-up Comments
Invalidate obsolete delete checks when the hook owner unmounts.
44-56: Minor · Stability & Availability · Quick win
Invalidate obsolete delete checks when the hook owner unmounts.
startDelete can publish after GeneralView unmounts. If the user returns to general before check(payload) resolves, the old continuation can open the new instance's confirmation or blocked dialog through the module-scoped handle. Add a request-generation guard and invalidate it during cleanup. Guard the error and finally paths so an obsolete request cannot publish or clear isChecking for a replacement request.
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.
The delete organization dialog gets its 480px width from a CSS class.
Apsara AlertDialog.Content has no width prop, so width={480} did nothing.
DeleteBlocker.count is optional. A refused delete carries no count, so
blockersFromError leaves it out instead of setting 0.
RESOURCES_EXIST has its own default line instead of the generic one.
toDeleteBlockers and the useDeleteFlow check take the proton Blocker,
DeleteBlockedPayload is imported from shared/types only, and the dialog
context is named DeleteBlockedDialogContext.
A handle created at module scope keeps its open state after the view
unmounts. A delete check that returned after the user left General, or
a dialog left open on browser Back, showed the dialog again on the next
visit. Base UI fixes this in v1.7.0 (mui/base-ui#4951), which Apsara
does not ship yet.
…iles
- Remove the enabled option from useTokens. Nothing passes it now.
- Remove the payload cast in DeleteBlockedDialogHost. The handle gives the type.
- Run prettier on the delete blocked dialog, useDeleteCheck and the delete organization dialog.
blockersFromError returns an empty list instead of an UNKNOWN blocker.
useDeleteCheck then shows an "Unable to delete" toast with the generic
message, so the blocked dialog opens only when it has something to list.
DeleteBlockedDialog now renders AlertDialog.Content, so a slot replaces
the whole visible dialog: it returns DeleteBlockedDialog, or its own
AlertDialog.Content with any width, layout and buttons. The SDK keeps
the dialog root, which owns the open state.
DeleteBlockedDialogHost is renamed to DeleteBlockedDialogRoot.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CheckOrganizationDeleteon click, with a spinner on the button. When something blocks the delete, an "Unable to delete" dialog lists the blockers. Otherwise the confirmation opens.FAILED_PRECONDITIONwithPreconditionFailureviolations) closes the confirmation and opens the same blocked dialog. AFAILED_PRECONDITIONwith no violations comes from a disabled organization and shows as its own blocker.FrontierProvidertakes aslotsprop. ItsdeleteBlockedDialogslot lets a host app word the blocked dialog in one place. The slot returnsDeleteBlockedDialog(title,description,blockers,messages), its ownAlertDialog.Contentto replace the whole dialog, orundefinedfor the SDK's own dialog. A bullet ismessages[subject], elsemessages[type], else the SDK line. Identical lines show once, and blockers with no line share one generic line.DeleteBlocker(type,subject,count) is the SDK's own shape. A check response and a refused delete both map to it. The server's developermessageis left out.useDeleteCheckruns the check, then opens the confirmation or the blocked dialog. The project flow in the next PR uses it too.@raystack/protonto94668c36, the commit the server builds from.Stack
Test plan
tsc --noEmitshows no new errors, eslint,pnpm build