Skip to content

Commit d873d1e

Browse files
feat: migrate views-new project files to use SetProjectMemberRole and RemoveProjectMember
Update the design-revamped SDK views to use the new atomic RPCs: - add-member-menu.tsx: use SetProjectMemberRole with fetched role UUID - remove-member-dialog.tsx: use RemoveProjectMember - project-details-view.tsx: use SetProjectMemberRole for role change Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 382eac3 commit d873d1e

File tree

3 files changed

+53
-81
lines changed

3 files changed

+53
-81
lines changed

web/sdk/react/views-new/projects/components/add-member-menu.tsx

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ import { useQuery, useMutation } from '@connectrpc/connect-query';
1616
import {
1717
FrontierServiceQueries,
1818
ListOrganizationUsersRequestSchema,
19-
CreatePolicyForProjectRequestSchema,
20-
type User
19+
ListRolesRequestSchema,
20+
SetProjectMemberRoleRequestSchema,
21+
type User,
22+
type Role
2123
} from '@raystack/proton/frontier';
2224
import { create } from '@bufbuild/protobuf';
2325
import { useFrontier } from '../../../contexts/FrontierContext';
@@ -80,8 +82,22 @@ export function AddMemberMenu({
8082
[orgUsers, members]
8183
);
8284

83-
const { mutate: createPolicyForProject } = useMutation(
84-
FrontierServiceQueries.createPolicyForProject,
85+
const { data: rolesData } = useQuery(
86+
FrontierServiceQueries.listRoles,
87+
create(ListRolesRequestSchema, {
88+
state: 'enabled',
89+
scopes: [PERMISSIONS.ProjectNamespace]
90+
}),
91+
{ enabled: !!projectId }
92+
);
93+
94+
const viewerRole = useMemo(
95+
() => (rolesData?.roles as Role[] ?? []).find((r: Role) => r.name === PERMISSIONS.RoleProjectViewer),
96+
[rolesData]
97+
);
98+
99+
const { mutate: setProjectMemberRole } = useMutation(
100+
FrontierServiceQueries.setProjectMemberRole,
85101
{
86102
onSuccess: () => {
87103
toastManager.add({
@@ -102,30 +118,32 @@ export function AddMemberMenu({
102118

103119
const addMember = useCallback(
104120
(userId: string) => {
105-
if (!userId || !organization?.id || !projectId) return;
106-
const principal = `${PERMISSIONS.UserNamespace}:${userId}`;
107-
createPolicyForProject(
108-
create(CreatePolicyForProjectRequestSchema, {
121+
if (!userId || !organization?.id || !projectId || !viewerRole?.id) return;
122+
setProjectMemberRole(
123+
create(SetProjectMemberRoleRequestSchema, {
109124
projectId,
110-
body: { roleId: PERMISSIONS.RoleProjectViewer, principal }
125+
principalId: userId,
126+
principalType: PERMISSIONS.UserNamespace,
127+
roleId: viewerRole.id
111128
})
112129
);
113130
},
114-
[createPolicyForProject, organization?.id, projectId]
131+
[setProjectMemberRole, organization?.id, projectId, viewerRole]
115132
);
116133

117134
const addTeam = useCallback(
118135
(teamId: string) => {
119-
if (!teamId || !organization?.id || !projectId) return;
120-
const principal = `${PERMISSIONS.GroupNamespace}:${teamId}`;
121-
createPolicyForProject(
122-
create(CreatePolicyForProjectRequestSchema, {
136+
if (!teamId || !organization?.id || !projectId || !viewerRole?.id) return;
137+
setProjectMemberRole(
138+
create(SetProjectMemberRoleRequestSchema, {
123139
projectId,
124-
body: { roleId: PERMISSIONS.RoleProjectViewer, principal }
140+
principalId: teamId,
141+
principalType: PERMISSIONS.GroupNamespace,
142+
roleId: viewerRole.id
125143
})
126144
);
127145
},
128-
[createPolicyForProject, organization?.id, projectId]
146+
[setProjectMemberRole, organization?.id, projectId, viewerRole]
129147
);
130148

131149
const toggleShowTeam = useCallback(() => {

web/sdk/react/views-new/projects/components/remove-member-dialog.tsx

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@ import { toastManager } from '@raystack/apsara-v1';
1111
import { useMutation } from '@connectrpc/connect-query';
1212
import {
1313
FrontierServiceQueries,
14-
ListPoliciesRequestSchema,
15-
DeletePolicyRequestSchema
14+
RemoveProjectMemberRequestSchema
1615
} from '@raystack/proton/frontier';
1716
import { create } from '@bufbuild/protobuf';
18-
import { useQuery } from '@connectrpc/connect-query';
1917

2018
export interface RemoveMemberPayload {
2119
memberId: string;
@@ -68,28 +66,19 @@ function RemoveMemberForm({
6866
}: RemoveMemberFormProps) {
6967
const [isLoading, setIsLoading] = useState(false);
7068

71-
const { data: policiesData } = useQuery(
72-
FrontierServiceQueries.listPolicies,
73-
create(ListPoliciesRequestSchema, {
74-
projectId: payload.projectId,
75-
userId: payload.memberId
76-
}),
77-
{ enabled: !!payload.projectId && !!payload.memberId }
78-
);
79-
80-
const policies = policiesData?.policies ?? [];
81-
82-
const { mutateAsync: deletePolicy } = useMutation(
83-
FrontierServiceQueries.deletePolicy
69+
const { mutateAsync: removeProjectMember } = useMutation(
70+
FrontierServiceQueries.removeProjectMember
8471
);
8572

8673
async function handleRemove() {
8774
setIsLoading(true);
8875
try {
89-
await Promise.all(
90-
policies.map(p =>
91-
deletePolicy(create(DeletePolicyRequestSchema, { id: p.id || '' }))
92-
)
76+
await removeProjectMember(
77+
create(RemoveProjectMemberRequestSchema, {
78+
projectId: payload.projectId,
79+
principalId: payload.memberId,
80+
principalType: 'app/user'
81+
})
9382
);
9483
toastManager.add({ title: 'Member removed', type: 'success' });
9584
refetch();

web/sdk/react/views-new/projects/project-details-view.tsx

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,15 @@ import deleteIcon from '../../assets/delete.svg';
2424
import { toastManager } from '@raystack/apsara-v1';
2525
import {
2626
useQuery,
27-
useMutation,
28-
createConnectQueryKey,
29-
useTransport
27+
useMutation
3028
} from '@connectrpc/connect-query';
31-
import { useQueryClient } from '@tanstack/react-query';
3229
import {
3330
FrontierServiceQueries,
3431
ListProjectGroupsRequestSchema,
3532
ListProjectUsersRequestSchema,
3633
GetProjectRequestSchema,
3734
ListRolesRequestSchema,
38-
CreatePolicyForProjectRequestSchema,
39-
DeletePolicyRequestSchema,
40-
ListPoliciesRequestSchema,
35+
SetProjectMemberRoleRequestSchema,
4136
type Role as ProtoRole
4237
} from '@raystack/proton/frontier';
4338
import { create } from '@bufbuild/protobuf';
@@ -289,49 +284,19 @@ export function ProjectDetailsView({
289284
]
290285
);
291286

292-
const queryClient = useQueryClient();
293-
const transport = useTransport();
294-
295-
const { mutateAsync: deletePolicy } = useMutation(
296-
FrontierServiceQueries.deletePolicy
297-
);
298-
const { mutateAsync: createPolicyForProject } = useMutation(
299-
FrontierServiceQueries.createPolicyForProject
287+
const { mutateAsync: setProjectMemberRole } = useMutation(
288+
FrontierServiceQueries.setProjectMemberRole
300289
);
301290

302291
const updateMemberRole = useCallback(
303292
async (memberId: string, isTeam: boolean, role: ProtoRole) => {
304293
try {
305-
const principal = isTeam
306-
? `${PERMISSIONS.GroupNamespace}:${memberId}`
307-
: `${PERMISSIONS.UserNamespace}:${memberId}`;
308-
309-
const input = create(ListPoliciesRequestSchema, {
310-
projectId,
311-
...(isTeam ? { groupId: memberId } : { userId: memberId })
312-
});
313-
314-
const policiesData = await queryClient.fetchQuery({
315-
queryKey: createConnectQueryKey({
316-
schema: FrontierServiceQueries.listPolicies,
317-
transport,
318-
input,
319-
cardinality: 'finite'
320-
})
321-
});
322-
323-
const policies = (policiesData as { policies?: { id?: string }[] })?.policies ?? [];
324-
325-
await Promise.all(
326-
policies.map(p =>
327-
deletePolicy(create(DeletePolicyRequestSchema, { id: p.id || '' }))
328-
)
329-
);
330-
331-
await createPolicyForProject(
332-
create(CreatePolicyForProjectRequestSchema, {
294+
await setProjectMemberRole(
295+
create(SetProjectMemberRoleRequestSchema, {
333296
projectId,
334-
body: { roleId: role.id as string, principal }
297+
principalId: memberId,
298+
principalType: isTeam ? PERMISSIONS.GroupNamespace : PERMISSIONS.UserNamespace,
299+
roleId: role.id as string
335300
})
336301
);
337302
refetchMembers();
@@ -350,7 +315,7 @@ export function ProjectDetailsView({
350315
});
351316
}
352317
},
353-
[queryClient, transport, deletePolicy, createPolicyForProject, projectId, refetchMembers]
318+
[setProjectMemberRole, projectId, refetchMembers]
354319
);
355320

356321
const handleDeleteSuccess = useCallback(() => {

0 commit comments

Comments
 (0)