From 78a7363579c1767c0ed7dcfe98bb52021c8b852e Mon Sep 17 00:00:00 2001 From: Abhishek Sah Date: Thu, 14 May 2026 15:26:06 +0530 Subject: [PATCH 1/2] refactor(sdk): drop redundant policy CRUD from remove-member-dialog After #1611, RemoveGroupUser's handler internally calls membership.RemoveGroupMember, which deletes the principal's group policies and clears both group#owner / group#member relations as one atomic-ish flow. The SDK's prior listPolicies + deletePolicy loop on top of that was a double-cleanup left over from the pre-migration era. Drops the listPolicies query, the deletePolicy mutation, and the associated proto schema imports. Behavior is unchanged from the user's perspective; one fewer round-trip and no SDK code touching app/group: policies directly. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../teams/components/remove-member-dialog.tsx | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/web/sdk/react/views-new/teams/components/remove-member-dialog.tsx b/web/sdk/react/views-new/teams/components/remove-member-dialog.tsx index e63115826..cfea24175 100644 --- a/web/sdk/react/views-new/teams/components/remove-member-dialog.tsx +++ b/web/sdk/react/views-new/teams/components/remove-member-dialog.tsx @@ -9,12 +9,10 @@ import { } from '@raystack/apsara-v1'; import { toastManager } from '@raystack/apsara-v1'; import { useFrontier } from '../../../contexts/FrontierContext'; -import { useMutation, useQuery } from '@connectrpc/connect-query'; +import { useMutation } from '@connectrpc/connect-query'; import { FrontierServiceQueries, - RemoveGroupUserRequestSchema, - ListPoliciesRequestSchema, - DeletePolicyRequestSchema + RemoveGroupUserRequestSchema } from '@raystack/proton/frontier'; import { create } from '@bufbuild/protobuf'; @@ -70,21 +68,6 @@ function RemoveMemberForm({ const [isLoading, setIsLoading] = useState(false); const { activeOrganization: organization } = useFrontier(); - const { data: policiesData } = useQuery( - FrontierServiceQueries.listPolicies, - create(ListPoliciesRequestSchema, { - groupId: payload.teamId, - userId: payload.memberId - }), - { enabled: !!payload.teamId && !!payload.memberId } - ); - - const policies = policiesData?.policies ?? []; - - const { mutateAsync: deletePolicy } = useMutation( - FrontierServiceQueries.deletePolicy - ); - const { mutateAsync: removeGroupUser } = useMutation( FrontierServiceQueries.removeGroupUser ); @@ -93,12 +76,6 @@ function RemoveMemberForm({ if (!organization?.id) return; setIsLoading(true); try { - await Promise.all( - policies.map(p => - deletePolicy(create(DeletePolicyRequestSchema, { id: p.id || '' })) - ) - ); - await removeGroupUser( create(RemoveGroupUserRequestSchema, { id: payload.teamId, From f6533f278e24cd0052cd0ac6ae166cca649c93d0 Mon Sep 17 00:00:00 2001 From: Abhishek Sah Date: Thu, 14 May 2026 15:30:16 +0530 Subject: [PATCH 2/2] fix(sdk): use handleConnectError in remove-member-dialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the generic "Something went wrong" toast with per-Connect-code branching so user-actionable errors surface specific messages: - InvalidArgument (last owner constraint) → "Cannot remove member" + the server's reason. - FailedPrecondition (not a member, disabled user) → same shape. - NotFound → "Not found" + server message. - PermissionDenied → "You don't have permission to perform this action". - Default → the generic toast, preserved for unknown errors. Matches the pattern @rsbh requested on #1609 for add-member-menu and team-details-view. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../teams/components/remove-member-dialog.tsx | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/web/sdk/react/views-new/teams/components/remove-member-dialog.tsx b/web/sdk/react/views-new/teams/components/remove-member-dialog.tsx index cfea24175..5e47f7fbd 100644 --- a/web/sdk/react/views-new/teams/components/remove-member-dialog.tsx +++ b/web/sdk/react/views-new/teams/components/remove-member-dialog.tsx @@ -15,6 +15,7 @@ import { RemoveGroupUserRequestSchema } from '@raystack/proton/frontier'; import { create } from '@bufbuild/protobuf'; +import { handleConnectError } from '../../../../utils/error'; export interface RemoveMemberPayload { memberId: string; @@ -88,11 +89,36 @@ function RemoveMemberForm({ refetch(); handle.close(); } catch (error) { - toastManager.add({ - title: 'Something went wrong', - description: - error instanceof Error ? error.message : 'Failed to remove member', - type: 'error' + handleConnectError(error, { + InvalidArgument: (e) => + toastManager.add({ + title: 'Cannot remove member', + description: e.message, + type: 'error' + }), + PermissionDenied: () => + toastManager.add({ + title: "You don't have permission to perform this action", + type: 'error' + }), + NotFound: (e) => + toastManager.add({ + title: 'Not found', + description: e.message, + type: 'error' + }), + FailedPrecondition: (e) => + toastManager.add({ + title: 'Cannot remove member', + description: e.message, + type: 'error' + }), + Default: (e) => + toastManager.add({ + title: 'Something went wrong', + description: e.message, + type: 'error' + }) }); } finally { setIsLoading(false);